ViewPager PagerAdapter nie aktualizuje widoku

Używam Viewpagera z biblioteki zgodności. Udało mi się wyświetlić kilka widoków, które mogę przeglądać.

Jednak ciężko mi się dowiedzieć, jak zaktualizować Viewpagera o nowy zestaw widoków.

Próbowałem różnych rzeczy, takich jak wywoływanie mAdapter.notifyDataSetChanged(), mViewPager.invalidate() nawet tworzenie zupełnie nowego adaptera za każdym razem, gdy chcę użyć nowej Listy danych.

Nic nie pomogło, tekst pozostaje niezmieniony od oryginału data.

Aktualizacja: Zrobiłem mały projekt testowy i prawie udało mi się zaktualizować widoki. Wkleję zajęcia poniżej.

To, co nie wydaje się aktualizować, to jednak drugi widok, " B " pozostaje, powinien wyświetlić "Y" po naciśnięciu przycisku aktualizacji.

public class ViewPagerBugActivity extends Activity {

    private ViewPager myViewPager;
    private List<String> data;

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

        data = new ArrayList<String>();
        data.add("A");
        data.add("B");
        data.add("C");

        myViewPager = (ViewPager) findViewById(R.id.my_view_pager);
        myViewPager.setAdapter(new MyViewPagerAdapter(this, data));

        Button updateButton = (Button) findViewById(R.id.update_button);
        updateButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                updateViewPager();
            }
        });
    }

    private void updateViewPager() {
        data.clear();
        data.add("X");
        data.add("Y");
        data.add("Z");
        myViewPager.getAdapter().notifyDataSetChanged();
    }

    private class MyViewPagerAdapter extends PagerAdapter {

        private List<String> data;
        private Context ctx;

        public MyViewPagerAdapter(Context ctx, List<String> data) {
            this.ctx = ctx;
            this.data = data;
        }

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

        @Override
        public Object instantiateItem(View collection, int position) {
            TextView view = new TextView(ctx);
            view.setText(data.get(position));
            ((ViewPager)collection).addView(view);
            return view;
        }

        @Override
        public void destroyItem(View collection, int position, Object view) {
             ((ViewPager) collection).removeView((View) view);
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == object;
        }

        @Override
        public Parcelable saveState() {
            return null;
        }

        @Override
        public void restoreState(Parcelable arg0, ClassLoader arg1) {
        }

        @Override
        public void startUpdate(View arg0) {
        }

        @Override
        public void finishUpdate(View arg0) {
        }
    }
}
Author: A-Sharabiani, 2011-08-31

30 answers

Można to osiągnąć na kilka sposobów.

Pierwsza opcja jest łatwiejsza, ale nieco bardziej nieefektywna.

Override getItemPosition in your PagerAdapter like this:

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

W ten sposób, po wywołaniu notifyDataSetChanged(), Pager widoku usunie wszystkie widoki i przeładuje je wszystkie. W ten sposób uzyskuje się efekt przeładowania.

Druga opcja, zasugerowana przez Alvaro Luisa Bustamante (poprzednio alvarolb) , to metoda setTag() w instantiateItem() podczas tworzenia instancji nowego widoku. Wtedy zamiast używać notifyDataSetChanged(), możesz użyć findViewWithTag(), aby znaleźć widok, który chcesz zaktualizować.

Drugie podejście jest bardzo elastyczne i wydajne. Chwała alvarolbowi za oryginalne badania.

 878
Author: rui.araujo,
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 11:47:29

Myślę, że w PagerAdapter nie ma żadnego błędu. Problem w tym, że zrozumienie, jak to działa, jest trochę skomplikowane. Patrząc na wyjaśnione tu rozwiązania, z mojego punktu widzenia dochodzi do nieporozumienia, a co za tym idzie do słabego wykorzystania instancyjnych poglądów.

Przez ostatnie kilka dni pracowałem z PagerAdapter i ViewPager i znalazłem następujące:

Metoda notifyDataSetChanged() na PagerAdapter powiadomi tylko ViewPager, że podstawowe strony uległy zmianie. Na przykład, jeśli tworzenie / usuwanie stron dynamicznie (dodawanie lub usuwanie elementów z listy) ViewPager powinno się tym zająć. W tym przypadku myślę, że ViewPager określa, czy nowy widok powinien zostać usunięty lub utworzony za pomocą metod getItemPosition() i getCount().

Myślę, że ViewPager, po wywołaniu notifyDataSetChanged() pobiera widok dziecka i sprawdza jego pozycję za pomocą getItemPosition(). Jeśli dla widoku potomnego ta metoda zwraca POSITION_NONE, ViewPager rozumie, że Widok został usunięty, wywołując destroyItem(), i usuwanie tego widoku.

W ten sposób zastąpienie getItemPosition(), aby zawsze zwracać POSITION_NONE jest całkowicie błędne, jeśli chcesz tylko zaktualizować zawartość stron, ponieważ wcześniej utworzone widoki zostaną zniszczone, a nowe będą tworzone za każdym razem, gdy wywołasz notifyDatasetChanged(). Może się wydawać, że nie jest tak źle tylko przez kilka {19]}s, ale gdy masz złożone widoki, takie jak listy wypełniane z bazy danych, może to być prawdziwy problem i strata zasobów.

Jest więc kilka podejścia do efektywnej zmiany zawartości widoku bez konieczności ponownego usuwania i tworzenia instancji widoku. To zależy od problemu, który chcesz rozwiązać. moim podejściem jest użycie metody setTag() dla dowolnego instancyjnego widoku w metodzie instantiateItem(). Jeśli chcesz zmienić dane lub unieważnić potrzebny Widok, możesz wywołać metodę findViewWithTag() w ViewPager, Aby pobrać wcześniej utworzony widok i zmodyfikować/używać go tak, jak chcesz, bez konieczności usuwania / tworzenia nowego widoku za każdym razem chcesz zaktualizować jakąś wartość.

Wyobraź sobie na przykład, że masz 100 stron z 100 TextViews I chcesz okresowo aktualizować tylko jedną wartość. Przy opisanych wcześniej podejściach oznacza to, że usuwasz i tworzysz instancję 100 TextViews przy każdej aktualizacji. To nie ma sensu...

 488
Author: Alvaro Luis Bustamante,
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-06 18:07:01

Zmień FragmentPagerAdapter na FragmentStatePagerAdapter.

Override getItemPosition() method and return POSITION_NONE.

W końcu będzie nasłuchiwać notifyDataSetChanged() w widoku pagera.

 85
Author: Kit,
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-12-17 21:04:13

ODPOWIEDŹ udzielona przez alvarolb jest zdecydowanie najlepszym sposobem, aby to zrobić. W oparciu o jego odpowiedź, łatwym sposobem na zaimplementowanie tego jest po prostu przechowywanie aktywnych widoków według pozycji: {]}

SparseArray<View> views = new SparseArray<View>();

@Override
public Object instantiateItem(View container, int position) {
    View root = <build your view here>;
    ((ViewPager) container).addView(root);
    views.put(position, root);
    return root;
}

@Override
public void destroyItem(View collection, int position, Object o) {
    View view = (View)o;
    ((ViewPager) collection).removeView(view);
    views.remove(position);
    view = null;
}

Następnie przez nadpisanie metody notifyDataSetChanged można odświeżyć widoki...

@Override
public void notifyDataSetChanged() {
    int key = 0;
    for(int i = 0; i < views.size(); i++) {
       key = views.keyAt(i);
       View view = views.get(key);
       <refresh view with new data>
    }
    super.notifyDataSetChanged();
}

Możesz użyć podobnego kodu w instantiateItem i notifyDataSetChanged, aby odświeżyć widok. W moim kodzie używam dokładnie tej samej metody.

 47
Author: Grimmace,
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:34:45

Miałem ten sam problem. Dla mnie zadziałało rozszerzenie FragmentStatePagerAdapter i nadpisanie poniższych metod:

@Override
public Parcelable saveState() {
    return null;
}

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

}
 28
Author: Mario Mosca,
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-07 05:08:15

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.
 20
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 11:55:03

Miałem ten sam problem i moim rozwiązaniem jest użycie {[1] } z nadpisaniem FragmentPagerAdapter#getItemId(int position):

@Override
public long getItemId(int position) {
    return mPages.get(position).getId();
}

Domyślnie metoda zwraca pozycję elementu. Przypuszczam, że ViewPager sprawdza, czy itemId została zmieniona i odtwarza Stronę tylko wtedy, gdy była. Ale nie - Wersja nadpisana zwraca tę samą pozycję co itemId, nawet jeśli strona jest inna, a ViewPager nie definiuje, że strona jest zastępowana i musi zostać odtworzona.

Aby tego użyć, long id jest potrzebne dla każdej strony. Zwykle oczekuje się, że być unikalne, ale proponuję, w tym przypadku, że po prostu powinien być inny od poprzedniej wartości dla tej samej strony. Możliwe jest więc zastosowanie licznika ciągłego w adapterze lub liczb losowych (o szerokim rozkładzie).

Myślę, że bardziej spójnym sposobem jest użycie tagów widoku wymienionych jako rozwiązanie w tym temacie. Ale prawdopodobnie nie we wszystkich przypadkach.

 9
Author: atlascoder,
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
2019-08-07 20:09:17

Znalazłem bardzo ciekawą decyzję tego problemu. Zamiast używać FragmentPagerAdapter , które przechowują w pamięci wszystkie fragmenty, możemy użyć FragmentStatePagerAdapter (android.wsparcie.v4.app.FragmentStatePagerAdapter), Ten fragment przeładowujemy za każdym razem, gdy go wybierzemy.

Realizacje obu adapterów są identyczne. Dlatego wystarczy zmienić " extend FragmentPagerAdapter " on " extend FragmentStatePagerAdapter "

 8
Author: Рома Богдан,
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-01 13:23:08

Po wielu poszukiwaniach tego problemu, znalazłem naprawdę dobre rozwiązanie, które moim zdaniem jest właściwym rozwiązaniem. Zasadniczo instantiateItem jest wywoływany tylko wtedy, gdy widok jest utworzony i nigdy więcej, dopóki widok nie zostanie zniszczony (tak się dzieje, gdy nadpisujesz funkcję getItemPosition, aby zwrócić POSITION_NONE). Zamiast tego, co chcesz zrobić, to zapisać utworzone widoki i albo zaktualizować je w adapterze, wygenerować funkcję get, aby ktoś inny mógł zaktualizuj go lub ustaw funkcję, która aktualizuje adapter (mój ulubiony).

Więc w myviewpageradapter dodaj zmienną w stylu:

private View updatableView;

An in your instantiateItem:

 public Object instantiateItem(View collection, int position) {
        updatableView = new TextView(ctx); //My change is here
        view.setText(data.get(position));
        ((ViewPager)collection).addView(view);
        return view;
    }

W ten sposób możesz utworzyć funkcję, która zaktualizuje twój Widok:

public updateText(String txt)
{
    ((TextView)updatableView).setText(txt);
}
Mam nadzieję, że to pomoże!
 5
Author: German,
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
2011-11-30 20:43:03

Dwa i pół roku po tym, jak po postawił swoje pytanie, ta kwestia jest nadal, cóż, nadal problemem. To oczywiste, że priorytet Google w tym nie jest szczególnie wysoki, więc zamiast znaleźć poprawkę, znalazłem obejście. Wielkim przełomem dla mnie było ustalenie, jaka jest prawdziwa przyczyna problemu (zobacz akceptowaną odpowiedź w Ten post). Gdy okazało się, że problem polegał na tym, że wszystkie aktywne strony nie są odpowiednio odświeżone, moje obejście było oczywiste: {]}

In my Fragment (the strony):

  • wziąłem cały kod, który wypełnia formularz z onCreateView i umieściłem go w funkcji o nazwie PopulateForm, która może być wywoływana z dowolnego miejsca, a nie przez framework. Ta funkcja próbuje uzyskać bieżący widok za pomocą getView, a jeśli to jest null, to po prostu powraca. Ważne jest, że PopulateForm zawiera tylko kod, który wyświetla - cały inny kod, który tworzy focuschange listeners i tym podobne, jest nadal w OnCreate
  • utworzyć boolean, który może być używane jako znacznik wskazujący, że formularz musi zostać przeładowany. Mój to mbReloadForm
  • nadpisuje OnResume (), aby wywołać PopulateForm (), jeśli mbReloadForm jest ustawione.

W mojej działalności, gdzie robię ładowanie stron:

  • przejdź do strony 0 zanim cokolwiek zmienisz. Używam FragmentStatePagerAdapter, więc wiem, że co najwyżej dwie lub trzy strony są dotknięte. Zmiana na stronę 0 zapewnia, że zawsze mam problem tylko na stronach 0, 1 i 2.
  • przed wyczyszczeniem starej listy, weź jest wielkości(). W ten sposób wiesz, ile stron jest dotkniętych błędem. Jeśli > 3, zmniejsz go do 3 - Jeśli używasz innego Pageradaptera, będziesz musiał zobaczyć, ile stron masz do czynienia z (Może wszystkie?)
  • Przeładuj Dane i wywołaj pageAdapter.notifyDataSetChanged ()
  • teraz dla każdej z dotkniętych stron sprawdź, czy strona jest aktywna za pomocą pagera.getChildAt ( i) - to mówi, Jeśli masz widok. Jeśli tak, zadzwoń do pagera.PopulateView (). Jeśli nie, Ustaw ReloadForm flaga.

Po tym, gdy przeładujesz drugi zestaw stron, błąd nadal spowoduje wyświetlenie starych danych. Jednak zostaną one teraz odświeżone i zobaczysz nowe dane - Twoi użytkownicy nie będą wiedzieli, że strona była niepoprawna, ponieważ to odświeżenie nastąpi zanim zobaczą stronę.

Mam nadzieję, że to komuś pomoże!

 5
Author: RichardP,
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:26:38

Wszystkie te rozwiązania mi nie pomogły. w ten sposób znalazłem działające rozwiązanie: Możesz za każdym razem, ale to nie wystarczy. należy to zrobić przed zmianą adaptera:

FragmentManager fragmentManager = slideShowPagerAdapter.getFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
List<Fragment> fragments = fragmentManager.getFragments();
for (Fragment f : fragments) {
    transaction.remove(f);
}
transaction.commit();

A potem:

viewPager.setAdapter(adapter);
 5
Author: Mahdi Perfect,
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-09-28 12:59:38

O wiele łatwiejszy sposób: użyj FragmentPagerAdapter, i zawiń swoje Paged widoki na fragmenty. Są aktualizowane

 5
Author: alfongj,
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-12-17 21:04:56

Dziękuję rui.araujo i Alvaro Luis Bustamante. Na początku staram się używać rui.droga araujo, bo to proste. To działa, ale gdy DANE się zmienią, strona będzie oczywiście przerysowana. Jest źle, więc staram się użyć sposobu Alvaro Luisa Bustamante. Idealnie. Oto kod:

@Override
protected void onStart() {
    super.onStart();
}

private class TabPagerAdapter extends PagerAdapter {
    @Override
    public int getCount() {
        return 4;
    }

    @Override
    public boolean isViewFromObject(final View view, final Object object) {
        return view.equals(object);
    }

    @Override
    public void destroyItem(final View container, final int position, final Object object) {
        ((ViewPager) container).removeView((View) object);
    }

    @Override
    public Object instantiateItem(final ViewGroup container, final int position) {
        final View view = LayoutInflater.from(
                getBaseContext()).inflate(R.layout.activity_approval, null, false);
        container.addView(view);
        ListView listView = (ListView) view.findViewById(R.id.list_view);
        view.setTag(position);
        new ShowContentListTask(listView, position).execute();
        return view;
    }
}

I gdy zmiana danych:

for (int i = 0; i < 4; i++) {
    View view = contentViewPager.findViewWithTag(i);
    if (view != null) {
        ListView listView = (ListView) view.findViewById(R.id.list_view);
        new ShowContentListTask(listView, i).execute();
    }
}
 5
Author: evan.z,
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-28 06:46:29

Na wszelki wypadek, gdyby ktoś używał adaptera bazującego na FragmentStatePagerAdapter (który pozwoli ViewPager stworzyć minimum stron potrzebnych do wyświetlenia, co najwyżej 2 w moim przypadku), @rui.odpowiedź araujo na nadpisanie getItemPosition w adapterze nie spowoduje znaczących strat, ale nadal można ją poprawić.

W pseudo kodzie:

public int getItemPosition(Object object) {
    YourFragment f = (YourFragment) object;
    YourData d = f.data;
    logger.info("validate item position on page index: " + d.pageNo);

    int dataObjIdx = this.dataPages.indexOf(d);

    if (dataObjIdx < 0 || dataObjIdx != d.pageNo) {
        logger.info("data changed, discard this fragment.");
        return POSITION_NONE;
    }

    return POSITION_UNCHANGED;
}
 4
Author: Jerry Tian,
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-11 05:56:38

ViewPager nie został zaprojektowany do obsługi dynamicznej zmiany widoku.

Potwierdziłem to szukając innego błędu związanego z tym https://issuetracker.google.com/issues/36956111 a w szczególności https://issuetracker.google.com/issues/36956111#comment56

To pytanie jest trochę stare, ale Google niedawno rozwiązało ten problem z ViewPager2 . Pozwoli to na zastąpienie ręcznie robionych (niezabezpieczonych i potencjalnie wadliwych) rozwiązań przez standardowy. Zapobiega również niepotrzebnemu odtwarzaniu Widoków, Tak jak robią to niektóre odpowiedzi.

Przykłady ViewPager2 można sprawdzić https://github.com/googlesamples/android-viewpager2

Jeśli chcesz użyć ViewPager2, musisz dodać następującą zależność do swojej kompilacji.plik gradle:

  dependencies {
     implementation 'androidx.viewpager2:viewpager2:1.0.0-beta02'
  }

Następnie możesz zamienić ViewPager w pliku xml na:

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

Następnie będziesz musiał zastąpić Viewpagera przez viewpager2 w Twoim aktywność

ViewPager2 wymaga RecyclerView.Adapter lub FragmentStateAdapter, w Twoim przypadku może to być RecyclerView.Adapter

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {

    private Context context;
    private ArrayList<String> arrayList = new ArrayList<>();

    public MyAdapter(Context context, ArrayList<String> arrayList) {
        this.context = context;
        this.arrayList = arrayList;
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(context).inflate(R.layout.list_item, parent, false);
        return new MyViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
        holder.tvName.setText(arrayList.get(position));
    }

    @Override
    public int getItemCount() {
        return arrayList.size();
    }

    public class MyViewHolder extends RecyclerView.ViewHolder {
        TextView tvName;

        public MyViewHolder(@NonNull View itemView) {
            super(itemView);
            tvName = itemView.findViewById(R.id.tvName);
        }
    }
} 
Jeśli używasz TabLayout, możesz użyć TabLayoutMediator :
        TabLayoutMediator tabLayoutMediator = new TabLayoutMediator(tabLayout, viewPager, true, new TabLayoutMediator.OnConfigureTabCallback() {
            @Override
            public void onConfigureTab(@NotNull TabLayout.Tab tab, int position) {
                // configure your tab here
                tab.setText(tabs.get(position).getTitle());
            }
        });

        tabLayoutMediator.attach();

Następnie będziesz mógł odświeżyć swoje widoki, modyfikując dane karty i wywołując metodę notifyDataSetChanged

 4
Author: Yves Delerm,
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
2019-08-07 11:43:31

Miałem podobny problem, w którym miałem cztery strony i jedna ze stron zaktualizowane widoki na pozostałych trzech. Udało mi się zaktualizować widżety (SeekBars, TextViews, itp.) na stronie sąsiadującej z bieżącą stroną. Dwie ostatnie strony miały nieaktywne widżety przy wywołaniu mTabsAdapter.getItem(position).

Aby rozwiązać mój problem, użyłem setSelectedPage(index) przed wywołaniem getItem(position). Spowoduje to utworzenie instancji strony, pozwalając mi na zmianę wartości i widżetów na każdej stronie.

Po całej aktualizacji chciałbym należy użyć setSelectedPage(position), po którym następuje notifyDataSetChanged().

Widać lekkie migotanie w widoku listy na głównej stronie aktualizacji, ale nic zauważalnego. Nie testowałem go dokładnie, ale to rozwiązuje mój bezpośredni problem.

 3
Author: enKoder,
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
2012-11-07 22:50:43

Po prostu zamieszczam tę odpowiedź na wypadek, gdyby ktoś inny uznał ją za przydatną. Aby zrobić dokładnie to samo, po prostu wziąłem kod źródłowy Viewpagera i Pageradaptera z biblioteki kompatybilności i skompilowałem go w moim kodzie(musisz uporządkować wszystkie błędy i zaimportować samodzielnie, ale na pewno można to zrobić).

Następnie w CustomViewPager Utwórz metodę o nazwie updateViewAt (int position). Sam widok można uzyskać z mitemów ArrayList zdefiniowanych w klasie ViewPager (należy ustawić Id dla widoków w pozycji instantiate i porównać ten id z pozycją w metodzie updateViewAt ()). Następnie możesz zaktualizować widok w razie potrzeby.

 3
Author: Naveen LP,
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-10-29 14:45:43

Chyba mam logikę Viewpagera.

Jeśli muszę odświeżyć zbiór stron i wyświetlić je na podstawie nowego zbioru danych, wywołuję notifyDataSetChanged () . Następnie ViewPager wykonuje szereg wywołań do getItemPosition(), przekazując tam Fragment jako obiekt. Ten Fragment może być albo ze starego zbioru danych (który chcę odrzucić), albo z nowego (który chcę wyświetlić). Więc nadpisuję getItemPosition () i tam muszę jakoś ustalić czy mój Fragment pochodzi ze starego lub nowego zbioru danych.

W moim przypadku mam układ 2-okienkowy z listą top items w lewym okienku i widok przesunięcia (ViewPager) po prawej stronie. Tak więc, przechowuję link do mojej bieżącej pozycji górnej wewnątrz mojej PagerAdapter, a także wewnątrz każdego fragmentu instancyjnej strony. Po zmianie wybranego górnego elementu na liście, zapisuję nowy górny element w PagerAdapter i wywołuję notifyDataSetChanged () . I w nadpisanym getItemPosition () porównuję górny element z mojego adaptera do górnego elementu z mojego fragmentu. i tylko jeśli nie są równe, zwracam POSITION_NONE. Następnie PagerAdapter ponownie identyfikuje wszystkie fragmenty, które zwróciły POSITION_NONE.

Uwaga. Przechowywanie top ID elementu zamiast referencji może być lepszym pomysłem.

Poniższy fragment kodu jest nieco schematyczny, ale zaadaptowałem go z faktycznie działającego kodu.

public class SomeFragment extends Fragment {
  private TopItem topItem;
}

public class SomePagerAdapter extends FragmentStatePagerAdapter {
  private TopItem topItem;

  public void changeTopItem(TopItem newTopItem) {
    topItem = newTopItem;
    notifyDataSetChanged();
  }

  @Override
  public int getItemPosition(Object object) {
    if (((SomeFragment) object).getTopItemId() != topItem.getId()) {
      return POSITION_NONE;
    }
    return super.getItemPosition(object);
  }
}

Dziękujemy wszystkim poprzednim badaczom!

 2
Author: Stanislav Karakhanov,
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-08 17:05:01

Poniższy kod zadziałał dla mnie.

Utwórz klasę, która rozszerza klasę FragmentPagerAdapter jak poniżej.

public class Adapter extends FragmentPagerAdapter {

private int tabCount;
private Activity mActivity;
private Map<Integer, String> mFragmentTags;
private FragmentManager mFragmentManager;
private int container_id;
private ViewGroup container;
private List<Object> object;

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

public Adapter(FragmentManager fm, int numberOfTabs , Activity mA) {
    super(fm);
    mActivity = mA;
    mFragmentManager = fm;
    object = new ArrayList<>();
    mFragmentTags = new HashMap<Integer, String>();
    this.tabCount = numberOfTabs;
}

@Override
public Fragment getItem(int position) {
    switch (position) {
        case 0:
            return Fragment0.newInstance(mActivity);
        case 1:
            return Fragment1.newInstance(mActivity);
        case 2:
            return Fragment2.newInstance(mActivity);
        default:
            return null;
    }}


@Override
public Object instantiateItem(ViewGroup container, int position) {
    Object object = super.instantiateItem(container, position);
    if (object instanceof Fragment) {
        Log.e("Already defined","Yes");
        Fragment fragment = (Fragment) object;
        String tag = fragment.getTag();
        Log.e("Fragment Tag","" + position + ", " + tag);
        mFragmentTags.put(position, tag);
    }else{
        Log.e("Already defined","No");
    }
    container_id = container.getId();
    this.container = container;
    if(position == 0){
        this.object.add(0,object);
    }else if(position == 1){
        this.object.add(1,object);
    }else if(position == 2){
        this.object.add(2,object);
    }
    return object;
}

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
    super.destroyItem(container, position, object);
    if (object instanceof Fragment) {
        Log.e("Removed" , String.valueOf(position));
    }
}

@Override
public int getItemPosition (Object object)
{   int index = 0;
    if(this.object.get(0) == object){
        index = 0;
    }else if(this.object.get(1) == object){
        index = 1;
    }else if(this.object.get(2) == object){
        index = 2;
    }else{
        index = -1;
    }
    Log.e("Index" , "..................." + String.valueOf(index));
    if (index == -1)
        return POSITION_NONE;
    else
        return index;
}

public String getFragmentTag(int pos){
    return "android:switcher:"+R.id.pager+":"+pos;
}

public void NotifyDataChange(){
    this.notifyDataSetChanged();
}

public int getcontainerId(){
    return container_id;
}

public ViewGroup getContainer(){
    return this.container;
}

public List<Object> getObject(){
    return this.object;
}

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

Następnie wewnątrz każdego utworzonego fragmentu Utwórz metodę updateFragment. W tej metodzie zmieniasz rzeczy, które musisz zmienić we fragmencie. Na przykład w moim przypadku Fragment0 zawierał GLSurfaceView, który wyświetla obiekt 3d oparty na ścieżce do .plik ply, więc wewnątrz mojej metody updateFragment zmieniam ścieżkę do tego pliku ply.

Następnie utwórz Instancja ViewPager,

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

I instancja Adpater,

adapter = new Adapter(getSupportFragmentManager(), 3, this);

Więc zrób to,

viewPager.setAdapter(adapter);
viewPager.setOffscreenPageLimit(1);

Następnie wewnątrz klasy zainicjowałeś klasę adaptera powyżej i utworzyłeś viewpagera, za każdym razem, gdy chcesz zaktualizować jeden z fragmentów (w naszym przypadku Fragment0) użyj następującego:

adapter.NotifyDataChange();

adapter.destroyItem(adapter.getContainer(), 0, adapter.getObject().get(0)); // destroys page 0 in the viewPager.

fragment0 = (Fragment0) getSupportFragmentManager().findFragmentByTag(adapter.getFragmentTag(0)); // Gets fragment instance used on page 0.

fragment0.updateFragment() method which include the updates on this fragment

adapter.instantiateItem(adapter.getContainer(), 0); // re-initialize page 0.
Rozwiązanie to oparte było na technice zaproponowanej przez Alvaro Luisa Bustamante.
 2
Author: Brainnovo,
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-02-18 11:59:12

Wiem, że jestem spóźniony, ale to może komuś pomóc. Przedłużam tylko zaakceptowaną odpowiedź i dodałem do niej komentarz.

Sama odpowiedź mówi, że jest nieefektywna.]}

Więc aby odświeżyć go tylko wtedy, gdy jest to wymagane, możesz to zrobić

private boolean refresh;

public void refreshAdapter() {
    refresh = true;
    notifyDataSetChanged();
}

@Override
public int getItemPosition(@NonNull Object object) {
    if (refresh) {
        refresh = false;
        return POSITION_NONE;
    } else {
        return super.getItemPosition(object);
    }
}
 2
Author: Harkal,
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
2020-08-03 09:08:29

1.Najpierw musisz ustawić metodę getItemposition w klasie Pageradapter 2.Musisz przeczytać dokładną pozycję pagera widoku 3.następnie wyślij tę pozycję jako lokalizację danych nowego 4.Zapisz Przycisk AKTUALIZACJI onclick listener wewnątrz setonpagechange listener

Ten kod programu jest trochę zmodyfikowany, aby ustawić tylko konkretny element pozycji

public class MyActivity extends Activity {

private ViewPager myViewPager;
private List<String> data;
public int location=0;
public Button updateButton;
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    data = new ArrayList<String>();
    data.add("A");
    data.add("B");
    data.add("C");
    data.add("D");
    data.add("E");
    data.add("F");

    myViewPager = (ViewPager) findViewById(R.id.pager);
    myViewPager.setAdapter(new MyViewPagerAdapter(this, data));

      updateButton = (Button) findViewById(R.id.update);

    myViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int i, float v, int i2) {
             //Toast.makeText(MyActivity.this, i+"  Is Selected  "+data.size(), Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onPageSelected( int i) {
          // here you will get the position of selected page
            final int k = i;
             updateViewPager(k);

        }

        @Override
        public void onPageScrollStateChanged(int i) {

        }
    });
}

private void updateViewPager(final int i) {  
    updateButton.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {

            Toast.makeText(MyActivity.this, i+"  Is Selected  "+data.size(), Toast.LENGTH_SHORT).show();
            data.set(i, "Replaced "+i);         
            myViewPager.getAdapter().notifyDataSetChanged();
        }
    });

}

private class MyViewPagerAdapter extends PagerAdapter {

    private List<String> data;
    private Context ctx;

    public MyViewPagerAdapter(Context ctx, List<String> data) {
        this.ctx = ctx;
        this.data = data;
    }

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

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

    @Override
    public Object instantiateItem(View collection, int position) {          

        TextView view = new TextView(ctx);
        view.setText(data.get(position));
        ((ViewPager)collection).addView(view);            
        return view;
    }

    @Override
    public void destroyItem(View collection, int position, Object view) {
         ((ViewPager) collection).removeView((View) view);
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view == object;
    }

    @Override
    public Parcelable saveState() {
        return null;
    }

    @Override
    public void restoreState(Parcelable arg0, ClassLoader arg1) {
    }

    @Override
    public void startUpdate(View arg0) {
    }

    @Override
    public void finishUpdate(View arg0) {
    }
}
}
 1
Author: Naveen Kumar,
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-01-06 09:09:53

viewPager.getAdapter().notifyDataSetChanged();

I w adapterze umieszczamy kod do aktualizacji widoku wewnątrz getItemPosition tak jak

@Override
public int getItemPosition(Object object) {

    if (object instanceof YourViewInViewPagerClass) { 
        YourViewInViewPagerClass view = (YourViewInViewPagerClass)object;
        view.setData(data);
    }

    return super.getItemPosition(object);
}

Może nie jest to najbardziej poprawny sposób, ale zadziałał (sztuczka spowodowała dla mnie awarię, więc nie było opcji)

 1
Author: Fonix,
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-09-28 12:58:58

Możesz dynamicznie aktualizować wszystkie fragmenty, możesz to zobaczyć w trzech krokach.

W adapterze:

public class MyPagerAdapter extends FragmentPagerAdapter {
private static int NUM_ITEMS = 3;
private Map<Integer, String> mFragmentTags;
private FragmentManager mFragmentManager;

public MyPagerAdapter(FragmentManager fragmentManager) {
    super(fragmentManager);
    mFragmentManager = fragmentManager;
    mFragmentTags = new HashMap<Integer, String>();
}

// Returns total number of pages
@Override
public int getCount() {
    return NUM_ITEMS;
}

// Returns the fragment to display for that page
@Override
public Fragment getItem(int position) {
    switch (position) {
        case 0:
            return FirstFragment.newInstance();
        case 1:
            return SecondFragment.newInstance();
        case 2:
            return ThirdFragment.newInstance();
        default:
            return null;
    }
}

// Returns the page title for the top indicator
@Override
public CharSequence getPageTitle(int position) {
    return "Page " + position;
}

@Override
public Object instantiateItem(ViewGroup container, int position) {
    Object object = super.instantiateItem(container, position);
    if (object instanceof Fragment) {
        Fragment fragment = (Fragment) object;
        String tag = fragment.getTag();
        mFragmentTags.put(position, tag);
    }
    return object;
}

public Fragment getFragment(int position) {
    Fragment fragment = null;
    String tag = mFragmentTags.get(position);
    if (tag != null) {
        fragment = mFragmentManager.findFragmentByTag(tag);
    }
    return fragment;
}}

Teraz w Twojej aktywności:

public class MainActivity extends AppCompatActivity implements ViewPager.OnPageChangeListener{

MyPagerAdapter mAdapterViewPager;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ViewPager viewPager = (ViewPager) findViewById(R.id.vpPager);
    mAdapterViewPager = new MyPagerAdapter(getSupportFragmentManager());
    viewPager.setAdapter(mAdapterViewPager);
    viewPager.addOnPageChangeListener(this);
}

@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

}

@Override
public void onPageSelected(int position) {

    Fragment fragment = mAdapterViewPager.getFragment(position);
    if (fragment != null) {
        fragment.onResume();
    }
}

@Override
public void onPageScrollStateChanged(int state) {

}}

W końcu w Twoim fragmencie coś w tym stylu:

public class YourFragment extends Fragment {

// newInstance constructor for creating fragment with arguments
public static YourFragment newInstance() {

    return new YourFragment();
}

// Store instance variables based on arguments passed
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
}

// Inflate the view for the fragment based on layout XML
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    return inflater.inflate(R.layout.fragment, container, false);
}


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

    //to refresh your view
    refresh();

}}

Możesz zobaczyć pełny kod tutaj .

Dzięki Alvaro Luis Bustamante.
 1
Author: Cabezas,
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-01-21 12:12:50

Zawsze zwracanie POSITION_NONE jest proste, ale trochę nieefektywne, ponieważ wywołuje instancję wszystkich stron, które już powstały.

Utworzyłem bibliotekę ArrayPagerAdapter do dynamicznej zmiany pozycji w Maperach Pageradapter.

Wewnętrznie, Adaptery tej biblioteki zwracają POSITION_NONE na getItemPosiition() tylko wtedy, gdy jest to konieczne.

Możesz zmieniać elementy dynamicznie, jak za pomocą tej biblioteki.

@Override
protected void onCreate(Bundle savedInstanceState) {
        /** ... **/
    adapter = new MyStatePagerAdapter(getSupportFragmentManager()
                            , new String[]{"1", "2", "3"});
    ((ViewPager)findViewById(R.id.view_pager)).setAdapter(adapter);
     adapter.add("4");
     adapter.remove(0);
}

class MyPagerAdapter extends ArrayViewPagerAdapter<String> {

    public MyPagerAdapter(String[] data) {
        super(data);
    }

    @Override
    public View getView(LayoutInflater inflater, ViewGroup container, String item, int position) {
        View v = inflater.inflate(R.layout.item_page, container, false);
        ((TextView) v.findViewById(R.id.item_txt)).setText(item);
        return v;
    }
}

Thils library obsługuje również strony utworzone przez Fragmenty.

 1
Author: T.Nakama,
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-04-04 10:57:06

To jest dla wszystkich takich jak ja, którzy muszą zaktualizować Viewpagera z Serwisu (lub innego wątku w tle) i żadna z propozycji nie zadziałała: Po odrobinie logcheckingu zdałem sobie sprawę, że metoda notifyDataSetChanged() nigdy nie powraca. getItemPosition (Object object) nazywa się tam wszystkie końce bez dalszego przetwarzania. Następnie znalazłem w dokumentach nadrzędnej klasy PagerAdapter (nie jest w dokumentach podklas), " zmiany zestawu danych muszą wystąpić w głównym wątku i muszą się zakończyć z wywołaniem notifyDataSetChanged() ". Tak więc rozwiązaniem roboczym w tym przypadku było (za pomocą FragmentStatePagerAdapter and getItemPosition (Object object) set to return POSITION_NONE):

A następnie wywołanie notifyDataSetChanged ():

runOnUiThread(new Runnable() {
         @Override
         public void run() {
             pager.getAdapter().notifyDataSetChanged();
         }
     });
 1
Author: Helmwag,
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-18 08:25:47

Możesz dodać transformację pagera na Viewpagerze w następujący sposób

myPager.setPageTransformer(true, new MapPagerTransform());

W poniższym kodzie zmieniłem kolor widoku na runtime podczas przewijania pagera

public class MapPagerTransform implements ViewPager.PageTransformer {

    public void transformPage(View view, float position) {
        LinearLayout showSelectionLL = (LinearLayout) view.findViewById(R.id.showSelectionLL);

        if (position < 0) {
            showSelectionLL.setBackgroundColor(Color.WHITE);
        } else if (position > 0) {
            showSelectionLL.setBackgroundColor(Color.WHITE);
        } else {
            showSelectionLL.setBackgroundColor(Color.RED);
        }
    }
}
 1
Author: Akshay dashore,
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
2020-08-03 11:34:52

Zamiast zwracać POSITION_NONE i ponownie tworzyć wszystkie fragmenty, możesz zrobić tak, jak sugerowałem tutaj: dynamicznie aktualizować Viewpagera?

 0
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-23 12:34:45

Myślę, że zrobiłem prosty sposób powiadamiania o zmianach zestawu danych:

Najpierw zmień trochę sposób działania funkcji instantiateItem:

    @Override
    public Object instantiateItem(final ViewGroup container, final int position) {
        final View rootView = mInflater.inflate(...,container, false);
        rootView.setTag(position);
        updateView(rootView, position);
        container.addView(rootView, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        mViewPager.setObjectForPosition(rootView, position);
        return rootView;
    }

Dla "updateView", wypełnij widok wszystkimi danymi, które chcesz wypełnić (setText, setBitmapImage,...) .

Sprawdź, czy destroyView działa tak:

    @Override
    public void destroyItem(final ViewGroup container, final int position, final Object obj) {
        final View viewToRemove = (View) obj;
        mViewPager.removeView(viewToRemove);
    }

Teraz Załóżmy, że musisz zmienić dane, zrobić to, a następnie wywołać następną funkcję na Pageradapterze:

    public void notifyDataSetChanged(final ViewPager viewPager, final NotifyLocation fromPos,
            final NotifyLocation toPos) {
        final int offscreenPageLimit = viewPager.getOffscreenPageLimit();
        final int fromPosInt = fromPos == NotifyLocation.CENTER ? mSelectedPhotoIndex
                : fromPos == NotifyLocation.MOST_LEFT ? mSelectedPhotoIndex - offscreenPageLimit
                        : mSelectedPhotoIndex + offscreenPageLimit;
        final int toPosInt = toPos == NotifyLocation.CENTER ? mSelectedPhotoIndex
                : toPos == NotifyLocation.MOST_LEFT ? mSelectedPhotoIndex - offscreenPageLimit
                        : mSelectedPhotoIndex + offscreenPageLimit;
        if (fromPosInt <= toPosInt) {
            notifyDataSetChanged();
            for (int i = fromPosInt; i <= toPosInt; ++i) {
                final View pageView = viewPager.findViewWithTag(i);
                mPagerAdapter.updateView(pageView, i);
            }
        }
    }

public enum NotifyLocation {
    MOST_LEFT, CENTER, MOST_RIGHT
}

Na przykład, jeśli chcesz powiadomić wszystkie widoki, które są wyświetlane przez viewPager, że coś się zmieniło, można wywołać:

notifyDataSetChanged(mViewPager,NotifyLocation.MOST_LEFT,NotifyLocation.MOST_RIGHT);
To wszystko.
 0
Author: android developer,
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-07-07 11:52:04

Jeśli to coś warte, na KitKat+ wydaje się, że adapter.notifyDataSetChanged() wystarczy, aby pokazać nowe widoki, pod warunkiem, że masz setOffscreenPageLimit wystarczająco wysokie. Jestem w stanie uzyskać pożądane zachowanie robiąc viewPager.setOffscreenPageLimit(2).

 0
Author: mszaro,
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-03-18 01:10:45

W zasadzie używam notifyDataSetChanged() Na ViewPager i CirclePageIndicator, a potem wywołuję destroyDrawingCache() na ViewPager i działa.. Żadne inne rozwiązanie nie zadziałało.

 0
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
2015-08-24 23:28:54