Ich habe eine Fragmentoberfläche mit Registerkarten am unteren Rand, die verschiedene Fragmente in der Hauptansicht öffnen.
Ich habe ein bestimmtes Fragment, das eine Liste von Elementen ist. Wenn der Benutzer eines der Elemente in dieser Liste auswählt, wird ein weiteres Fragment geöffnet, das einen Viewpager enthält, der horizontal zwischen allen Elementen in der Liste im vorherigen Fragment scrollt. Das funktioniert super.
Der Viewpager verwendet einen FragmentPagerAdapter, um die Elemente anzuzeigen.
Das Problem tritt auf, wenn der Benutzer ein Element in der Liste auswählt, es anzeigt, dann auf die Schaltfläche in der Registerkartenleiste klickt, um zur Liste zurückzukehren, und dann ein anderes Element auswählt. Bei der zweiten Auswahl eines Elements wird anstelle des Viewpagers ein leerer Bildschirm angezeigt. In diesem Fall erhalte ich keine Fehler in meinem LogCat.
Warum wird der Viewpager nur beim ersten Mal angezeigt?
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
undFragmentStatePagerAdapter
besteht darin, dass Ersteres für wenige Seiten besser geeignet ist. Alle Fragmente bleiben im Speicher, wodurch die besten Leistungen beim Seitenwechsel erzielt werden, während Letzteres für viele Seiten besser geeignet ist Seiten, es zerstört Fragmente, behält nur ihren Zustand bei, es ist speichereffizienter, aber beim Seitenwechsel etwas langsamer.Ich habe es geschafft, dies durch Ersetzen
getFragmentManager()
durchgetChildFragmentManager()
im übergeordneten Fragment zu lösen . Dieses übergeordnete Fragment instanziierte einen android.support.v4.app.FragmentPagerAdapter, um pageable (verschiebbare) Fragmente zu enthalten, für die ein Fragmentmanager im Konstruktor erforderlich ist. An diesen Konstruktor habe ich den Rückgabewert von übergebengetChildFragmentManager()
.Der Link von hackbod war der Schlüssel ( https://developer.android.com/about/versions/android-4.2.html#NestedFragments ), der in diesem Beitrag Fragmente in Fragmenten gefunden wurde
quelle
FragmentStatePagerAdapter
wird die hier gestellte Frage nicht gelöst. zusammen mitFragmentStatePagerAdapter
im übergeordneten FragmentYourAdapter adapter = new YourAdapter (getChildFragmentManager());
muss hinzugefügt werdenfür mich musste ich das auf meinem viewpager aufrufen:
Ich hatte das Problem, dass der Viewpager nicht aktualisiert wurde und ich nur einen leeren weißen Bildschirm sah, auf dem sich die Fragmente befinden sollten. Ich habe getChildFragmentManager übergeben, aber es hat nicht geholfen.
quelle
In meinem speziellen Fall, in dem ich ein CoordinatorLayout mit einem AppBarLayout und dem ViewPager verwendet habe, wurde das Problem für mich gelöst, indem ich das Android: fitSystemWindows = "true" aus meinen AppBarLayout-XML-Eigenschaften entfernte .
Frag mich nicht warum. Ich weiß, es klingt ein bisschen lächerlich und sollte keine Korrelation haben, aber es war diese einzige Zeile, die das einzige Problem verursachte, da ich bereits getChildFragmentManager () in meinem Adapter verwendet habe. Ich habe einen ganzen Tag damit verbracht, meinen Code zu debuggen, um dies zu finden. Ich hoffe, dass dies jemand anderem Zeit spart.
quelle
Ich hatte das gleiche Problem, für das ich den Adapter von
FragmentPagerAdapter
zuFragmentStatePagerAdapter
undgetFragmentManager()
im übergeordneten Fragment auf geändert habegetChildFragmentManager()
Der Grund dafür ist
FragmentStatePagerAdapter
hilfreich beim Speichern einer großen Anzahl von Seiten, und der mit jeder besuchten Seite verknüpfte Speicher ist geringer, da nur der gespeicherte Status des Fragments beibehalten wird, während die Seite nicht sichtbar ist. Dies reduziert den Overhead beim Umschalten zwischen den Fragmenten.quelle
Versuchen Sie setzen
setOffscreenPageLimit (int limit)
auf Eltern ViewPager.Das hat bei mir wie Charme funktioniert.
In meinem Fall hatte ich Fragment
TabLayout
mitViewPager.
Und noch eine
ViewPager
in diesem Fragment. Das erste Mal funktioniert alles einwandfrei, aber wenn ich die Registerkarte wechsle und zurückkehre, ist ein Teil meines Fragments leer.quelle
Das würde dir helfen.
quelle
Wir haben dies umgangen, indem wir die View-Pager-Elemente als Standardansichten und nicht als Fragmente erneut implementiert und den Adapter entsprechend geändert haben.
quelle
Ich habe das gleiche Problem auf Xamarin Android mit einem leeren Bildschirm beim zweiten Mal bekommen. Die folgenden Einstellungen haben es für mich behoben.
quelle
Sie können den Adapter auch für Fälle initialisieren, in denen dieser Fehler auftritt, wenn Ihre App minimiert und später aufgerufen wird.
quelle
Ich hatte das gleiche, beim zweiten Aufruf des Pager-Adapters gab die untergeordnete Ansicht eine NullPointerException zurück. Und das Ändern des Adapters in FragmentStatePagerAdapter löst auch mein Problem.
quelle
Wechseln Sie
FragmentPagerAdapter
inFragmentStatePagerAdapter
VerwendunggetChildFragmentManager()
anstelle vongetFragmentManager()
getChildFragmentManager()
- weil laut Dokumentation ein privater FragmentManager zum Platzieren und Verwalten von Fragmenten innerhalb dieses Fragments zurückgegeben wird. In der ZwischenzeitgetFragmentManager()
wird der FragmentManager für die Interaktion mit Fragmenten zurückgegeben, die dieser Aktivität zugeordnet sindquelle
Klasse ViewPagerAdapter erweitert FragmentStatePagerAdapter diese Arbeit für mich versuchen Sie dies
quelle