Mam interfejs fragmentów z zakładkami na dole, które otwierają różne fragmenty w głównym widoku.
Mam jeden konkretny fragment, który jest listą pozycji. Jeśli użytkownik wybierze jedną z pozycji na tej liście, otwiera się kolejny fragment zawierający przeglądarkę, która przewija się w poziomie pomiędzy wszystkimi pozycjami na liście w poprzednim fragmencie. To działa świetnie.
Viewpager używa FragmentPagerAdapter do wyświetlenia elementów.
Problem pojawia się, gdy użytkownik wybiera element na liście, wyświetla go, a następnie naciska przycisk na pasku kart, aby wrócić do listy, a następnie wybiera inny element. Za drugim razem, gdy element jest zaznaczony, zamiast przeglądarki pojawia się pusty ekran. W takim przypadku w moim LogCacie nie pojawiają się żadne błędy.
Dlaczego przeglądarka pojawia się tylko za pierwszym razem?
FragmentPagerAdapter:
public class ViewPagerAdapter extends FragmentPagerAdapter {
Cursor mCursor;
public ViewPagerAdapter(FragmentManager fm, Cursor c) {
super(fm);
mCursor = c;
}
public void changeCursor(Cursor c) {
mCursor = c;
this.notifyDataSetChanged();
}
@Override
public int getCount() {
if (mCursor == null) return 0;
else return mCursor.getCount();
}
@Override
public Fragment getItem(int position) {
mCursor.moveToPosition(position);
return TeamCardFragment.newInstance(mCursor, position);
}
}
PagerFragment:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Bundle bundle = getArguments();
mCursorPosition = bundle.getInt(TeamCardCommon.BUNDLE_KEY_CURSOR_POSITION);
View mView = inflater.inflate(R.layout.team_card_master, container, false);
mViewPager = (ViewPager)mView.findViewById(R.id.team_card_master_view_pager);
mAdapter = new ViewPagerAdapter(getFragmentManager(), cursor);
new setAdapterTask().execute();
return mView;
}
private class setAdapterTask extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... params) {
return null;
}
@Override
protected void onPostExecute(Void result) {
mViewPager.setAdapter(mAdapter);
mViewPager.setCurrentItem(mCursorPosition);
}
}
FragmentPagerAdapter
iFragmentStatePagerAdapter
jest w tym pierwszym jest bardziej odpowiedni dla kilku stron, zachowuje wszystkie fragmenty w pamięci, dzięki czemu ma najlepsze wyniki przy przełączaniu stron, podczas gdy ten drugi jest bardziej odpowiedni dla wielu stron, niszczy fragmenty, zachowując tylko ich stan, jest bardziej wydajna w pamięci, ale trochę wolniejsza na przełączaniu stron.Udało mi się rozwiązać ten problem poprzez zastąpienie
getFragmentManager()
zegetChildFragmentManager()
we fragmencie nadrzędnym. Ten fragment nadrzędny tworzył instancję android.support.v4.app.FragmentPagerAdapter w celu zawarcia stronicowanych (przesuwalnych) fragmentów, co wymaga menedżera fragmentów w konstruktorze. Do tego konstruktora przekazałem zwracaną wartośćgetChildFragmentManager()
.Kluczem był link hackbod ( https://developer.android.com/about/versions/android-4.2.html#NestedFragments ), który został znaleziony w tym poście Fragments within Fragments
źródło
FragmentStatePagerAdapter
samo użycie nie rozwiązuje zadanego tutaj pytania. wraz zFragmentStatePagerAdapter
w rodzicielskim fragmencieYourAdapter adapter = new YourAdapter (getChildFragmentManager());
należy dodaćdla mnie musiałem to nazwać na moim podglądzie:
Miałem problem, w którym przeglądarka nie odświeżała się, a jedyne, co widziałem, to pusty biały ekran, w którym powinny znajdować się fragmenty. Przechodziłem przez getChildFragmentManager, ale to nie pomogło.
źródło
W moim bardzo szczególnym przypadku, gdy korzystałem z CoordinatorLayout z AppBarLayout i ViewPager, tym, co mnie rozwiązało, było usunięcie androida: fitSystemWindows = "true" z moich właściwości xml AppBarLayout .
Nie pytaj mnie dlaczego. Wiem, że brzmi to trochę absurdalnie i jakby nie powinno mieć żadnej korelacji, ale to właśnie ta pojedyncza linia była jedyną rzeczą, która powodowała problemy, ponieważ już używałem getChildFragmentManager () w moim adapterze. Spędziłem cały dzień na debugowaniu mojego kodu, aby to znaleźć, więc mam nadzieję, że zaoszczędzi to komuś innego czasu.
źródło
Miałem ten sam problem, dla którego zmieniłem adapter z
FragmentPagerAdapter
naFragmentStatePagerAdapter
iwgetFragmentManager()
nadrzędnym fragmencie nagetChildFragmentManager()
Przyczyna tego jest
FragmentStatePagerAdapter
pomocna w przechowywaniu dużej liczby stron, a pamięć związana z każdą odwiedzaną stroną jest mniejsza, ponieważ zachowuje tylko zapisany stan fragmentu, podczas gdy strona nie jest widoczna. Zmniejsza to obciążenie podczas przełączania między fragmentami.źródło
Spróbować umieścić
setOffscreenPageLimit (int limit)
na macierzystej ViewPager.To zadziałało na mnie jak urok.
W moim przypadku miałem fragment wnętrza
TabLayout
zViewPager.
I jeszcze jeden
ViewPager
wewnątrz tego fragmentu. Za pierwszym razem wszystko działało dobrze, ale kiedy zmieniam kartę i wracam, część mojego fragmentu zniknęła.źródło
To by ci pomogło.
źródło
Rozwiązaliśmy ten problem, ponownie implementując elementy pagera widoku jako standardowe widoki zamiast fragmentów i odpowiednio zmieniając adapter.
źródło
Otrzymałem ten sam problem na platformie Xamarin Android z pustym ekranem za drugim razem .. Ustawienie poniższego rozwiązało problem.
źródło
Możesz również zainicjować adapter w przypadkach, w których występuje ten błąd, gdy aplikacja jest zminimalizowana, a później wywoływana.
źródło
Miałem to samo, gdy po raz drugi wywołuję adapter pagera, widok potomny zwraca wyjątek NullPointerException. A zmiana adaptera w FragmentStatePagerAdapter rozwiązuje również mój problem.
źródło
Zmień
FragmentPagerAdapter
naFragmentStatePagerAdapter
UżyjgetChildFragmentManager()
zamiastgetFragmentManager()
getChildFragmentManager()
- ponieważ zgodnie z dokumentacją zwróci prywatny FragmentManager do umieszczania i zarządzania fragmentami wewnątrz tego fragmentu. W międzyczasiegetFragmentManager()
zwróci FragmentManager do interakcji z fragmentami powiązanymi z tym działaniemźródło
klasa ViewPagerAdapter rozszerza FragmentStatePagerAdapter tę pracę dla mnie spróbuj tego
źródło