Aktualizować ViewPager dynamicznie?

Nie mogę zaktualizować zawartości w ViewPager.

Pytanie: Jaka jest relacja i prawidłowe użycie metod instantiateItem() i getItem () w klasie FragmentPagerAdapter?

Używałem tylko getItem () do tworzenia instancji i zwracania moich fragmentów:

@Override
public Fragment getItem(int position) {
    return new MyFragment(context, paramters);
}

To działało dobrze (ale jak powiedziałem, nie mogę zmienić treści).

Więc znalazłem to: ViewPager PagerAdapter nie aktualizuje widoku

Szczególny, w którym mówi się o metodzie instantiateItem ():

"moim podejściem jest użycie metody setTag () dla dowolnego instantiated view w metodzie instantiateItem ()"

Więc teraz chcę zaimplementować instantiateItem () w tym celu. Ale nie wiem co mam tam zwrócić (return is Object) i jaka jest relacja z getItem (int position)?

Obecnie używam getItem do tworzenia instancji fragmentu, czy to źle? Ale czy muszę wstawiać fragmenty do zmiennej instancji, czy nie implementacja getItem () w ogóle...? Po prostu tego nie rozumiem.

Próbowałem przeczytać odniesienie :

  • Public abstract Fragment getItem (int position)

    Zwraca Fragment związany z określoną pozycją.

  • Public Object instantiateItem (ViewGroup container, int position)

    Utwórz stronę dla podanej pozycji. Adapter jest odpowiedzialny za dodanie widoku do podanego tutaj kontenera, chociaż musi tylko zapewnić, że zostanie to wykonane do czasu powrotu z finishUpdate (ViewGroup). Parametry

    Kontener zawierający widok, w którym strona będzie wyświetlana. ustaw pozycję strony, która ma zostać utworzona.

    Zwraca

    Zwraca obiekt reprezentujący nową stronę. Nie musi to być Widok, ale może to być inny kontener strony.

... ale nadal nie rozumiem, jak są ze sobą spokrewnieni i co Muszę to zrobić.

Oto Mój kod. Używam pakietu wsparcia v4.

ViewPagerTest

public class ViewPagerTest extends FragmentActivity {
    private ViewPager pager;
    private MyFragmentAdapter adapter; 

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.pager1);

        pager = (ViewPager)findViewById(R.id.slider);

        String[] data = {"page1", "page2", "page3", "page4", "page5", "page6"};

        adapter = new MyFragmentAdapter(getSupportFragmentManager(), 6, this, data);
        pager.setAdapter(adapter);

        ((Button)findViewById(R.id.button)).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                reload();
            }
        });
    }

    private void reload() {
        String[] data = {"changed1", "changed2", "changed3", "changed4", "changed5", "changed6"};
        //adapter = new MyFragmentAdapter(getSupportFragmentManager(), 6, this, data);
        adapter.setData(data);
        adapter.notifyDataSetChanged();
        pager.invalidate();

        //pager.setCurrentItem(0);
    }
}

MyFragmentAdapter

class MyFragmentAdapter extends FragmentPagerAdapter {
    private int slideCount;
    private Context context;
    private String[] data;

    public MyFragmentAdapter(FragmentManager fm, int slideCount, Context context, String[] data) {
        super(fm);
        this.slideCount = slideCount;
        this.context = context;
        this.data = data;
    }

    @Override
    public Fragment getItem(int position) {
        return new MyFragment(data[position], context);
    }

    @Override
    public int getCount() {
        return slideCount;
    }

    public void setData(String[] data) {
        this.data = data;
    }

    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }
}

MyFragment

public final class MyFragment extends Fragment {
    private String text;

    public MyFragment(String text, Context context) {
        this.text = text;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.slide, null);
        ((TextView)view.findViewById(R.id.text)).setText(text);

        return view;
    }
}

Tutaj jest też ktoś z podobnym problemem, bez odpowiedzi...

Http://www.mail-archive.com/[email protected]/msg200477.html

Author: Community, 2012-06-01

18 answers

Używając FragmentPagerAdapter lub FragmentStatePagerAdapter, najlepiej jest zajmować się wyłącznie getItem() i w ogóle nie dotykać instantiateItem(). Na instantiateItem()-destroyItem()-isViewFromObject() Interfejs na PagerAdapter jest niższym poziomem interfejsu, którego FragmentPagerAdapter używa do implementacji znacznie prostszego interfejsu getItem().

Zanim przejdę do tego, powinienem wyjaśnić, że

Jeśli chcesz wyłączyć wyświetlane fragmenty, musisz unikać FragmentPagerAdapter i używać / Align = "center" bgcolor = "# e0ffe0 " / cesarz chin / / align = center /

Wcześniejsza wersja tej odpowiedzi popełniła błąd, używając FragmentPagerAdapter jako przykładu - to nie zadziała, ponieważ FragmentPagerAdapter nigdy nie niszczy fragment po wyświetleniu go za pierwszym razem.

Nie polecam obejścia setTag() i findViewWithTag() podanego w linkowanym poście. Jak już odkryłeś, używanie setTag() i findViewWithTag() nie działa z fragmentami, więc nie jest to dobre dopasowanie.

Właściwym rozwiązaniem jest override getItemPosition(). Po wywołaniu notifyDataSetChanged(), ViewPager wywołuje getItemPosition() na wszystkich elementach w adapterze, aby sprawdzić, czy należy je przenieść do innej pozycji, czy usunąć.

Domyślnie, getItemPosition() zwraca POSITION_UNCHANGED, co oznacza, " ten obiekt jest w porządku tam, gdzie jest, nie niszcz ani nie usuwaj go."Zwrócenie POSITION_NONE rozwiązuje problem, zamiast tego mówiąc:" ten obiekt nie jest już elementem, który wyświetlam, usuń go."Pozwala to na usunięcie i odtworzenie każdego elementu w adapterze.

To jest całkowicie legalne rozwiązanie! Ta poprawka sprawia, że notifydataset changed zachowuje się jak zwykły Adapter bez recyklingu widoku. Jeśli zastosujesz tę poprawkę i osiągi są zadowalające, wyruszasz na wyścigi. Zrobione.

Jeśli potrzebujesz lepszej wydajności, możesz użyć implementacji fancier getItemPosition(). Oto przykład dla pagera tworzącego fragmenty z listy ciągów:

ViewPager pager = /* get my ViewPager */;
// assume this actually has stuff in it
final ArrayList<String> titles = new ArrayList<String>();

FragmentManager fm = getSupportFragmentManager();
pager.setAdapter(new FragmentStatePagerAdapter(fm) {
    public int getCount() {
        return titles.size();
    }

    public Fragment getItem(int position) {
        MyFragment fragment = new MyFragment();
        fragment.setTitle(titles.get(position));
        return fragment;
    }

    public int getItemPosition(Object item) {
        MyFragment fragment = (MyFragment)item;
        String title = fragment.getTitle();
        int position = titles.indexOf(title);

        if (position >= 0) {
            return position;
        } else {
            return POSITION_NONE;
        }
    }
});

Z tą implementacją, tylko fragmenty wyświetlające nowe tytuły otrzymają wyświetlane. Wszelkie fragmenty wyświetlające tytuły, które nadal znajdują się na liście, zostaną przeniesione do nowej pozycji na liście, a fragmenty z tytułami, które w ogóle nie znajdują się na liście, zostaną zniszczone.

Co jeśli fragment nie został odtworzony, ale i tak wymaga aktualizacji? Aktualizacje żywego fragmentu są najlepiej obsługiwane przez sam fragment. Na tym polega zaleta posiadania fragmentu-to przecież jego własny kontroler. Fragment może dodać słuchacza lub obserwator do innego obiektu w onCreate(), a następnie usuń go w onDestroy(), zarządzając tym samym samą aktualizacją. Nie musisz umieszczać całego kodu aktualizacji wewnątrz getItem(), tak jak w adapterze dla ListView lub innych typów AdapterView.

Jeszcze jedno-to, że FragmentPagerAdapter nie niszczy fragmentu, nie oznacza, że getItemPosition jest całkowicie bezużyteczny w FragmentPagerAdapter. Nadal można użyć tego wywołania zwrotnego, aby zmienić kolejność fragmentów w Viewpagerze. Nigdy nie usunie jednak całkowicie z FragmentManager.

 554
Author: Bill Phillips,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-03 16:28:00

Zamiast zwracać POSITION_NONE z getItemPosition() i powodować odtwarzanie pełnego widoku, zrób to:

//call this method to update fragments in ViewPager dynamically
public void update(UpdateData xyzData) {
    this.updateData = xyzData;
    notifyDataSetChanged();
}

@Override
public int getItemPosition(Object object) {
    if (object instanceof UpdateableFragment) {
        ((UpdateableFragment) object).update(updateData);
    }
    //don't return POSITION_NONE, avoid fragment recreation. 
    return super.getItemPosition(object);
}

Twoje fragmenty powinny zaimplementować UpdateableFragment Interfejs:

public class SomeFragment extends Fragment implements
    UpdateableFragment{

    @Override
    public void update(UpdateData xyzData) {
         // this method will be called for every fragment in viewpager
         // so check if update is for this fragment
         if(forMe(xyzData)) {
           // do whatever you want to update your UI
         }
    }
}

I interfejs:

public interface UpdateableFragment {
   public void update(UpdateData xyzData);
}

Twoja klasa danych:

public class UpdateData {
    //whatever you want here
}
 126
Author: M-WaJeEh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-16 08:09:14

Dla tych, którzy nadal borykają się z tym samym problemem, z którym miałem do czynienia wcześniej, gdy mam Viewpagera z fragmentami 7. domyślne dla tych fragmentów, aby załadować angielską zawartość z usługi api, ale problem tutaj, że chcę zmienić język z aktywności ustawień i po zakończeniu ustawienia aktywność chcę ViewPager w głównej aktywności, aby odświeżyć fragmenty, aby dopasować wybór języka od użytkownika i załadować zawartość arabską, jeśli użytkownik wybrał Arabski tutaj, co zrobiłem, aby działać od pierwszego czas

1- Musisz użyć FragmentStatePagerAdapter, jak wspomniano powyżej.

2-Na main activity nadpisałem onResume i zrobiłem następujące

 if (!(mPagerAdapter == null)) {
mPagerAdapter.notifyDataSetChanged();
}

3-nadpisałem getItemPosition () w mPagerAdapter i zwracam POSITION_NONE.

 @Override
   public int getItemPosition(Object object) {
     return POSITION_NONE;
    }

Działa jak urok

 15
Author: Ziad Gholmish,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-23 11:34:00

Napotkałem ten problem i w końcu go rozwiązałem dzisiaj, więc zapisuję to, czego się nauczyłem i mam nadzieję, że będzie to pomocne dla kogoś, kto jest nowy w Androidzie ViewPager i aktualizować tak jak ja. Używam FragmentStatePagerAdapter w API level 17 i obecnie mam tylko 2 fragmenty. Myślę, że coś jest nie tak, proszę mnie poprawić, dzięki. Tutaj wpisz opis obrazka

  1. Serializowane dane muszą być wczytane do pamięci. Można to zrobić za pomocą CursorLoader/AsyncTask/Thread. To, czy zostanie załadowany automatycznie, zależy na Twój kod. Jeśli używasz CursorLoader, jest ona automatycznie ładowana, ponieważ istnieje zarejestrowany obserwator danych.

  2. Po wywołaniu viewpager.setAdapter(pageradapter), adapter {[7] } jest stale wywoływany do budowania fragmentów. Więc jeśli dane są ładowane, getCount() może zwrócić 0, więc nie musisz tworzyć fałszywych fragmentów dla żadnych pokazanych danych.

  3. Po załadowaniu danych adapter nie będzie automatycznie budował fragmentów, ponieważ getCount() nadal ma wartość 0, więc możemy ustawić rzeczywiście załadowany numer danych na zwracane przez getCount(), następnie wywołaj adapter notifyDataSetChanged(). ViewPager zacznij tworzyć fragmenty (tylko pierwsze 2 fragmenty) z danych w pamięci. Robi się to przed zwróceniem notifyDataSetChanged(). Wtedy ViewPager ma odpowiednie fragmenty, których potrzebujesz.

  4. Jeżeli zarówno dane w bazie danych jak i w pamięci są aktualizowane (write through), albo tylko dane w pamięci są aktualizowane (write back), albo tylko dane w bazie danych są aktualizowane. W dwóch ostatnich przypadkach, gdy dane nie są automatycznie ładowane z bazy danych do pamięci (jako wspomniane wyżej). Adapter ViewPager i pager zajmują się tylko danymi w pamięci.

  5. Więc kiedy dane w pamięci są aktualizowane, wystarczy wywołać adapter notifyDataSetChanged(). Ponieważ fragment jest już utworzony, adapter onItemPosition() zostanie wywołany przed powrotem notifyDataSetChanged(). Nic nie trzeba robić w getItemPosition(). Następnie dane są aktualizowane.

 14
Author: oscarthecat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-08 22:33:44

Spróbuj destroyDrawingCache() Na Viewpagerze po notifyDataSetChanged() w kodzie.

 12
Author: czaku,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-19 06:09:00

Po godzinach frustracji, próbując wszystkich powyższych rozwiązań, aby przezwyciężyć ten problem, a także próbując wielu rozwiązań na inne podobne pytania, takie jak to, to i to które nie udało mi się rozwiązać tego problemu i zrobić ViewPager zniszczyć stare Fragment i wypełnić pager nowymi Fragments. rozwiązałem problem w następujący sposób:{[32]]}

1) Ustaw klasę ViewPager na extends FragmentPagerAdapter jako po:

 public class myPagerAdapter extends FragmentPagerAdapter {

2) Tworzenie pozycji dla ViewPager, które przechowują title i fragment w następujący sposób:

public class PagerItem {
private String mTitle;
private Fragment mFragment;


public PagerItem(String mTitle, Fragment mFragment) {
    this.mTitle = mTitle;
    this.mFragment = mFragment;
}
public String getTitle() {
    return mTitle;
}
public Fragment getFragment() {
    return mFragment;
}
public void setTitle(String mTitle) {
    this.mTitle = mTitle;
}

public void setFragment(Fragment mFragment) {
    this.mFragment = mFragment;
}

}

3) aby konstruktor ViewPager wziął moją instancję FragmentManager, aby przechowywał ją w mojej class w następujący sposób:

private FragmentManager mFragmentManager;
private ArrayList<PagerItem> mPagerItems;

public MyPagerAdapter(FragmentManager fragmentManager, ArrayList<PagerItem> pagerItems) {
    super(fragmentManager);
    mFragmentManager = fragmentManager;
    mPagerItems = pagerItems;
}

4) Utwórz metodę, aby ponownie ustawić adapter dane z nowymi danymi, usuwając wszystkie poprzednie fragment z samej fragmentManager, aby {[17] } ponownie ustawić nowe fragment z nowej listy jako po:

public void setPagerItems(ArrayList<PagerItem> pagerItems) {
    if (mPagerItems != null)
        for (int i = 0; i < mPagerItems.size(); i++) {
            mFragmentManager.beginTransaction().remove(mPagerItems.get(i).getFragment()).commit();
        }
    mPagerItems = pagerItems;
}

5) Z kontenera Activity lub Fragment nie inicjuj ponownie adaptera nowymi danymi. Ustaw nowe dane za pomocą metody setPagerItems z nowymi danymi w następujący sposób:

ArrayList<PagerItem> pagerItems = new ArrayList<PagerItem>();
    pagerItems.add(new PagerItem("Fragment1", new MyFragment1()));
    pagerItems.add(new PagerItem("Fragment2", new MyFragment2()));

    mPagerAdapter.setPagerItems(pagerItems);
    mPagerAdapter.notifyDataSetChanged();
Mam nadzieję, że to pomoże.
 10
Author: Sami Eltamawy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:32

Z jakiegoś powodu żadna z odpowiedzi nie zadziałała dla mnie, więc musiałem zastąpić metodę restoreState bez wywoływania super w moim fragmentStatePagerAdapter. Kod:

private class MyAdapter extends FragmentStatePagerAdapter {

    // [Rest of implementation]

    @Override
    public void restoreState(Parcelable state, ClassLoader loader) {}

}
 7
Author: hordurh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-18 15:41:47

Lekko zmodyfikowałem rozwiązanie dostarczone przez Billa Phillipsa, aby zaspokoić moje potrzeby

private class PagerAdapter extends FragmentStatePagerAdapter{
    Bundle oBundle;
    FragmentManager oFragmentManager;
    ArrayList<Fragment> oPooledFragments;

public PagerAdapter(FragmentManager fm) {
    super(fm);
    oFragmentManager=fm;

    }
@Override
public int getItemPosition(Object object) {

    Fragment oFragment=(Fragment)object;
    oPooledFragments=new ArrayList<>(oFragmentManager.getFragments());
    if(oPooledFragments.contains(oFragment))
        return POSITION_NONE;
    else
        return POSITION_UNCHANGED;
    } 
}

Tak, że getItemPosition() zwraca POSITION_NONE tylko dla tych fragmentów, które są obecnie w FragmentManager, gdy wywołane jest getItemPosition. (Zauważ, że to FragmentStatePager i ViewPager z nim związane są zawarte w fragmencie Nie w aktywności)

 3
Author: adwait,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-27 13:22:15

Miałem podobny problem, ale nie chcę ufać istniejącym rozwiązaniom (ciężko zakodowane nazwy znaczników itp.) I nie mogłem sprawić, by rozwiązanie M-WaJeEh działało dla mnie. Oto moje rozwiązanie:

Przechowuję odniesienia do fragmentów utworzonych w getItem w tablicy. Działa to dobrze, dopóki aktywność nie zostanie zniszczona z powodu zmiany konfiguracji lub braku pamięci lub czegokolwiek innego (-->po powrocie do aktywności fragmenty powracają do swojego ostatniego stanu bez ponownego wywołania 'getItem' i w ten sposób bez aktualizacji tablicy).

Aby uniknąć tego problemu zaimplementowałem instantiateItem(ViewGroup, int) i zaktualizowałem tam moją tablicę, tak:

        @Override
    public Object instantiateItem(ViewGroup container, int position) {
        Object o = super.instantiateItem(container, position);
        if(o instanceof FragmentX){
            myFragments[0] = (FragmentX)o;
        }else if(o instanceof FragmentY){
            myFragments[1] = (FragmentY)o;
        }else if(o instanceof FragmentZ){
            myFragments[2] = (FragmentZ)o;
        }
        return o;
    }

Więc z jednej strony cieszę się, że znalazłem rozwiązanie, które działa na mnie i chciałem się nim z wami podzielić, ale chciałem też zapytać, czy ktoś inny próbował czegoś podobnego i czy jest jakiś powód, dla którego nie powinienem tego robić w ten sposób? Jak na razie działa to bardzo dobrze dla mnie...

 2
Author: jpm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-06 12:00:56

Jeśli chcesz użyć FragmentStatePagerAdapter, zapoznaj się z https://code.google.com/p/android/issues/detail?can=2&start=0&num=100&q=&colspec=ID%20Type%20Status%20Owner%20Summary%20Stars&groupby=&sort=&id=37990. Istnieją problemy z FragmentStatePagerAdapter, które mogą lub nie mogą utrudniać twojego przypadku użycia.

Również link ma kilka rozwiązań..kilka może odpowiadać Twoim wymaganiom.

 1
Author: cgr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-22 08:54:14

Przeżyłem ten sam problem i za dużo razy Szukałem. Jakakolwiek Odpowiedź udzielona w stackoverflow lub przez google nie była rozwiązaniem mojego problemu. Mój problem był łatwy. Mam listę, pokazuję tę listę za pomocą viewpagera. Kiedy dodaję nowy element do nagłówka listy i odświeżam viewpagera nic się nie zmieniło. Moje ostateczne rozwiązanie było bardzo łatwe, każdy może użyć. Gdy nowy element dodany do listy i chcesz odświeżyć listę. Najpierw ustaw adapter viewpager na null, a następnie odtworz adapter i ustaw na to do viewpagera.

myVPager.setAdapter(null);
myFragmentAdapter = new MyFragmentAdapter(getSupportFragmentManager(),newList);
myVPager.setAdapter(myFragmentAdapter);

Upewnij się, że twój adapter musi rozszerzyć FragmentStatePagerAdapter

 1
Author: nebyan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-15 07:58:30

Używam biblioteki EventBus do aktualizacji zawartości Fragment w ViewPager. Logika jest prosta, podobnie jak dokument eventbus jak to zrobić. Nie ma potrzeby kontrolowania instancji FragmentPagerAdapter. Kod jest tutaj:

1: Zdefiniuj zdarzenia

Określ, która wiadomość jest potrzebna do aktualizacji.

public class UpdateCountEvent {
    public final int count;

    public UpdateCountEvent(int count) {
        this.count = count;
    }
}

2.Przygotuj abonentów

Wpisz poniższy kod we fragmencie, który jest potrzebny do aktualizacji.

@Override
public void onStart() {
    super.onStart();
    EventBus.getDefault().register(this);
}

@Override
public void onStop() {
    EventBus.getDefault().unregister(this);  
    super.onStop();
}

public void onEvent(UpdateCountEvent event) {//get update message
    Toast.makeText(getActivity(), event.count, Toast.LENGTH_SHORT).show();
}

3.Post events

Wpisz poniżej kod w inne Activity lub inne Fragment który wymaga aktualizacji parametru

//input update message
EventBus.getDefault().post(new UpdateCountEvent(count));
 0
Author: Fantasy Fang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-13 09:38:40

Próbowałem tak wielu różnych podejść, że żaden nie rozwiązał mojego problemu. Poniżej przedstawiam, jak rozwiązuję to za pomocą kombinacji rozwiązań dostarczonych przez was wszystkich. Dziękuję wszystkim.

class PagerAdapter extends FragmentPagerAdapter {

    public boolean flag_refresh=false;

    public PagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int page) {
        FragmentsMain f;
        f=new FragmentsMain();
        f.page=page;
        return f;
    }

    @Override
    public int getCount() {
        return 4;
    }

    @Override
    public int getItemPosition(Object item) {
        int page= ((FragmentsMain)item).page;

        if (page == 0 && flag_refresh) {
            flag_refresh=false;
            return POSITION_NONE;
        } else {
            return super.getItemPosition(item);
        }
    }

    @Override
    public void destroyItem(View container, int position, Object object) {

        ((ViewPager) container).removeView((View) object);
    }
}

Chcę odświeżyć stronę 0 tylko po onresume ().

 adapter=new PagerAdapter(getSupportFragmentManager());
 pager.setAdapter(adapter);

@Override
protected void onResume() {
    super.onResume();

    if (adapter!=null) {
        adapter.flag_refresh=true;
        adapter.notifyDataSetChanged();
    }
}

W moim fragmencie znajduje się Publiczna liczba całkowita "page", która może mi powiedzieć, czy jest to strona, którą chcę odświeżyć.

public class FragmentsMain extends Fragment {

private Cursor cursor;
private static Context context;
public int page=-1;
 0
Author: Ted Hsieh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-17 01:38:18

Wiem, że jestem spóźniona na przyjęcie. Naprawiłem problem dzwoniąc TabLayout#setupWithViewPager(myViewPager); zaraz po FragmentPagerAdapter#notifyDataSetChanged();

 0
Author: theapache64,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-12 03:35:41

To rozwiązanie nie będzie działać dla wszystkich, ale w moim przypadku każdy Fragment w moim Viewpagerze jest inną klasą i tylko jeden z nich istnieje na raz.

Dzięki temu ograniczeniu rozwiązanie to jest bezpieczne i powinno być bezpieczne w użyciu w produkcji.

private void updateFragment(Item item) {

    List<Fragment> fragments = getSupportFragmentManager().getFragments();
    for (Fragment fragment : fragments) {

        if (fragment instanceof MyItemFragment && fragment.isVisible()) {
            ((MyItemFragment) fragment).update(item);
        }

    }
}

Jeśli masz kilka wersji tego samego fragmentu, możesz użyć tej samej strategii, aby wywołać metody na tych fragmentach, aby określić, czy jest to fragment, który chcesz zaktualizować.

 0
Author: Kevin Grant,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-06 18:00:37

Może to komuś pomóc - w moim przypadku podczas wstawiania nowej strony Pager dwukrotnie pytał o pozycję istniejącego fragmentu, ale nie pytał o pozycję nowego elementu, powodując nieprawidłowe zachowanie i nie wyświetlanie danych.

  1. Skopiuj źródło dla FragmentStatePagerAdapter (wydaje się, że nie było aktualizowane od wieków).

  2. Override notifyDataSetChanged ()

    @Override
    public void notifyDataSetChanged() {
        mFragments.clear();
        super.notifyDataSetChanged();
    }
    
  3. Dodaj test sanity do destroyItem (), aby zapobiec awarie:

    if (position < mFragments.size()) {
        mFragments.set(position, null);
    }
    
 0
Author: Meanman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-23 13:34:38

Przejrzałem wszystkie odpowiedzi powyżej i kilka innych postów, ale nadal nie mogłem znaleźć czegoś, co działało dla mnie(z różnymi typami fragmentów wraz z dynamicznym dodawaniem i usuwaniem kart). Podejście FWIW działa dla mnie (na wypadek, gdyby ktoś inny miał takie same problemy).

public class MyFragmentStatePageAdapter extends FragmentStatePagerAdapter {
    private static final String TAB1_TITLE = "Tab 1";
    private static final String TAB2_TITLE = "Tab 2";
    private static final String TAB3_TITLE = "Tab 3";

    private ArrayList<String> titles = new ArrayList<>();
    private Map<Fragment, Integer> fragmentPositions = new HashMap<>();


    public MyFragmentStatePageAdapter(FragmentManager fm) {
        super(fm);
    }


    public void update(boolean showTab1, boolean showTab2, boolean showTab3) {
        titles.clear();

        if (showTab1) {
            titles.add(TAB1_TITLE);
        }
        if (showTab2) {
            titles.add(TAB2_TITLE);
        }
        if (showTab3) {
            titles.add(TAB3_TITLE);
        }
        notifyDataSetChanged();
    }


    @Override
    public int getCount() {
        return titles.size();
    }

    @Override
    public Fragment getItem(int position) {
        Fragment fragment = null;

        String tabName = titles.get(position);
        if (tabName.equals(TAB1_TITLE)) { 
            fragment =  Tab1Fragment.newInstance();
        } else if (tabName.equals(TAB2_TITLE)) {
            fragment =  Tab2Fragment.newInstance();
        } else if (tabName.equals(TAB3_TITLE)) {
            fragment =  Tab3Fragmen.newInstance();
        } 

        ((BaseFragment)fragment).setTitle(tabName);
        fragmentPositions.put(fragment, position);
        return fragment;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return titles.get(position);
    }

    @Override
    public int getItemPosition(Object item) {
        BaseFragment fragment = (BaseFragment)item;
        String title = fragment.getTitle();
        int position = titles.indexOf(title);

        Integer fragmentPosition = fragmentPositions.get(item);
        if (fragmentPosition != null && position == fragmentPosition) {
            return POSITION_UNCHANGED;
        } else {
            return POSITION_NONE;
        }
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        super.destroyItem(container, position, object);
        fragmentPositions.remove(object);
    }
}
 0
Author: John O'Reilly,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-05 20:32:07

Użyj FragmentStatePagerAdapter zamiast FragmentPagerAdapter jeśli chcesz odtworzyć lub przeładować fragment na podstawie indeksu Na przykład, jeśli chcesz przeładować fragment inny niż FirstFragment, możesz sprawdzić instancję i zwrócić pozycję w następujący sposób

 public int getItemPosition(Object item) {
    if(item instanceof FirstFragment){
       return 0;
    }
    return POSITION_NONE;
 }
 0
Author: HemangNirmal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-11 14:09:09