Mamy tutaj bardzo dziwny problem z ViewPager. Osadzamy listy na każdej stronie ViewPager i wyzwalamy notifyDataSetChanged zarówno w adapterze list, jak i adapterze pagera widoku podczas aktualizowania danych listy.
Zauważyliśmy, że czasami strona nie aktualizuje swojego drzewa widoku, tzn. Pozostaje pusta, a czasami nawet znika po przejściu do niej. Podczas kilkukrotnego przewijania w tę iz powrotem zawartość nagle pojawi się ponownie. Wygląda na to, że Android nie ma tutaj aktualizacji widoku. Zauważyłem również, że podczas debugowania za pomocą przeglądarki hierarchii wybranie widoku zawsze spowoduje, że pojawi się on ponownie, najwyraźniej dlatego, że przeglądarka hierarchii zmusza wybrany widok do ponownego rysowania.
Nie mogłem jednak zrobić tego programowo; unieważnienie widoku listy lub nawet całego pagera widoku nie przyniosło żadnego efektu.
Dzieje się tak z biblioteką compliance-v4_r7. Próbowałem również użyć najnowszej wersji, ponieważ twierdzi, że naprawia wiele problemów związanych z wyświetlaniem pagera, ale to pogorszyło sprawę (na przykład gesty zostały zepsute, aby czasami nie pozwalały mi przeglądać wszystkich stron).
Czy ktoś inny też ma te problemy, czy masz pojęcie, co może je powodować?
źródło
Jeśli
ViewPager
jest ustawiona wewnątrz fragmentu z aFragmentPagerAdapter
, użyjgetChildFragmentManager()
zamiastgetSupportFragmentManager()
jako parametru, aby zainicjowaćFragmentPagerAdapter
.mAdapter = new MyFragmentPagerAdapter(getChildFragmentManager());
Zamiast
mAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager());
źródło
getItem()
na zasadzieFragmentPagerAdapter
, która została zagnieżdżona w odtworzonym fragmentem.Miałem dokładnie ten sam problem, ale faktycznie zniszczyłem widok w destruItem (pomyślałem). Problemem jednak było to, że zniszczył go za pomocą
viewPager.removeViewAt(index);
instedviewPager.removeView((View) object);
Źle:
@Override public void destroyItem(ViewGroup viewPager, int position, Object object) { viewPager.removeViewAt(position); }
Dobrze:
@Override public void destroyItem(ViewGroup viewPager, int position, Object object) { viewPager.removeView((View) object); }
źródło
ViewPager próbuje robić sprytne rzeczy związane z ponownym wykorzystaniem przedmiotów, ale wymaga zwrócenia nowych pozycji przedmiotów, gdy sytuacja się zmieni. Spróbuj dodać to do swojego PagerAdapter:
public int getItemPosition (Object object) { return POSITION_NONE; }
Zasadniczo mówi ViewPager, że wszystko się zmieniło (i zmusza go do ponownego utworzenia instancji). To jedyna rzecz, o której przychodzi mi do głowy.
źródło
return POSITION_NONE;
,forces it to re-instantiate everything
ale w moim przypadku nie chcę ponownie tworzyć instancji wszystkiego , więc czy byłoby możliwe usunięcieview
bez czyszczenia istniejących rzeczy? Daj mi znaćPróbowałem zbyt wielu rozwiązań, ale nieoczekiwanie
viewPager.post()
zadziałałomAdapter = new NewsVPAdapter(getContext(), articles); viewPager.post(new Runnable() { @Override public void run() { viewPager.setAdapter(mAdapter); } });
źródło
Biblioteka obsługi systemu Android ma działanie demonstracyjne, które zawiera ViewPager z ListView na każdej stronie. Powinieneś prawdopodobnie spojrzeć i zobaczyć, co robi.
W Eclipse (z Android Dev Tools r20):
New > Android Sample Project
Support4Demos
Android Tools > Add Support Library
Fragment
a następniePager
Kod do tego znajduje się w
src/com.example.android.supportv4.app/FragmentPagerSupport.java
. Powodzenia!źródło
Wpadłem na to i miałem bardzo podobne problemy. Zapytałem nawet o przepełnienie stosu.
Dla mnie, w rodzicu rodzica mojego zdania, ktoś podklasował
LinearLayout
i przejmowałrequestLayout()
bez dzwonieniasuper.requestLayout()
. Zapobiegło to wywołaniuonMeasure
ionLayout
wywołaniu na moim ViewPager (chociaż hierarchyviewer ręcznie je wywołuje). Bez pomiaru będą wyświetlane jako puste w ViewPager.Sprawdź więc swoje widoki zawierające. Upewnij się, że podklasy są z View i nie przesłaniają ślepo requestLayout ani niczego podobnego.
źródło
Miałem ten sam problem, który ma coś wspólnego
ListView
(ponieważ mój pusty widok pojawia się dobrze, jeśli lista jest pusta). Właśnie zadzwoniłemrequestLayout()
do problemuListView
. Teraz rysuje się dobrze!źródło
Napotkałem ten sam problem podczas korzystania z ViewPager i FragmentStatePagerAdapter. Próbowałem użyć programu obsługi z 3-sekundowym opóźnieniem, aby wywołać unieważnienie () i requestLayout (), ale to nie zadziałało. Co zadziałało, to zresetowanie koloru tła viewPagera w następujący sposób:
MyFragment.java
private Handler mHandler; private Runnable mBugUpdater; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = new ViewPager(getActivity()); //...Create your adapter and set it here... mHandler = new Handler(); mBugUpdater = new Runnable(){ @Override public void run() { mVp.setBackgroundColor(mItem.getBackgroundColor()); mHandler = null; mBugUpdater = null; } }; mHandler.postDelayed(mBugUpdater,50); return rootView; } @Override public void onPause() { if(mHandler != null){ //Remove the callback if it hasn't triggered yet mHandler.removeCallbacks(mBugUpdater); mHandler = null; mBugUpdater = null; } super.onPause(); }
źródło
Miałem problem z tymi samymi objawami, ale z inną przyczyną, która okazała się głupim błędem z mojej strony. Pomyślałem, że dodam to tutaj na wypadek, gdyby to komuś pomogło.
Miałem ViewPagera używającego FragmentStatePagerAdapter, który miał dwa fragmenty, ale później dodałem trzeci. Zapomniałem jednak, że domyślny limit strony poza ekranem to 1 - więc gdy przełączyłem się na nowy trzeci fragment, pierwszy zostałby zniszczony, a następnie odtworzony po przełączeniu z powrotem. Problem polegał na tym, że moja aktywność była odpowiedzialna za powiadamianie tych fragmentów o zainicjowaniu ich stanu interfejsu użytkownika. Zdarzyło się to zadziałać, gdy cykle życia aktywności i fragmentów były takie same, ale aby to naprawić, musiałem zmienić fragmenty, aby zainicjować ich własny interfejs użytkownika podczas ich cyklu życia uruchamiania. Na koniec zmieniłem również setOffscreenPageLimit na 2, aby wszystkie trzy fragmenty były zawsze żywe (bezpieczne w tym przypadku, ponieważ nie wymagały dużej ilości pamięci).
źródło
Miałem podobny problem. Buforuję widoki, ponieważ potrzebuję tylko 3 widoków w formacie
ViewPager
. Kiedy przesuwam się do przodu, wszystko jest w porządku, ale kiedy zaczynam się przesuwać do tyłu, pojawia się błąd, mówi się, że „mój widok ma już rodzica”. Rozwiązaniem jest ręczne usuwanie niepotrzebnych elementów.@Override public Object instantiateItem(ViewGroup container, int position) { int localPos = position % SIZE; TouchImageView view; if (touchImageViews[localPos] != null) { view = touchImageViews[localPos]; } else { view = new TouchImageView(container.getContext()); view.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); touchImageViews[localPos] = view; } view.setImageDrawable(mDataModel.getPhoto(position)); Log.i(IRViewPagerAdpt.class.toString(), "Add view " + view.toString() + " at pos: " + position + " " + localPos); if (view.getParent() == null) { ((ViewPager) container).addView(view); } return view; } @Override public void destroyItem(ViewGroup container, int position, Object view) { // ((ViewPager) container).removeView((View) view); Log.i(IRViewPagerAdpt.class.toString(), "remove view " + view.toString() + " at pos: " + position); } .................. private static final int SIZE = 3; private TouchImageView[] touchImageViews = new TouchImageView[SIZE];
źródło
Dla mnie problem polegał na powrocie do działania po zabiciu procesu aplikacji. Używam niestandardowego adaptera pagera widoku zmodyfikowanego ze źródeł systemu Android. Pager widoku jest osadzony bezpośrednio w działaniu.
Powołanie
viewPager.setCurrentItem(position, true);
(z animacją) po ustawieniu danych i notifyDataSetChanged () wydaje się działać, ale jeśli parametr jest ustawiony na false, nie działa i fragment jest pusty. To skrajny przypadek, który może komuś pomóc.
źródło