Ich kann das Fragment in FragmentPagerAdapter nicht wiederverwenden. Mit der destroyItem () - Methode löscht es das Fragment, ruft es aber immer noch nicht als getItem () auf. Es gibt nur 2-3 Bilder.
public class ExamplePagerAdapter extends FragmentPagerAdapter {
ArrayList < String > urls;
int size = 0;
public ExamplePagerAdapter(FragmentManager fm, ArrayList < String > res) {
super(fm);
urls = res;
size = urls.size();
}
@Override
public int getCount() {
if (urls == null) {
return 0;
} else {
return size;
}
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
FragmentManager manager = ((Fragment) object).getFragmentManager();
FragmentTransaction trans = manager.beginTransaction();
trans.remove((Fragment) object);
trans.commit();
}
@Override
public Fragment getItem(int position) {
Fragment fragment = new FloorPlanFragment();
Bundle b = new Bundle();
b.putInt("p", position);
b.putString("image", urls.get(position));
Log.i("image", "" + urls.get(position));
fragment.setArguments(b);
return fragment;
}
}
Und in FragmentActivity,
pager.setAdapter(new ExamplePagerAdapter(getSupportFragmentManager(), res2));
KISS Antwort:
Einfache Verwendung von FragmentStatePagerAdapter anstelle von FragmentPagerAdapter .
Ich bekam die Antwort .. Zuerst dachte ich, diese Frage zu löschen, da ich einen sehr dummen Fehler mache, aber diese Antwort wird jemandem helfen, der vor dem gleichen Problem steht, dass anstelle von FragmentPagerAdapter
FragmentStatePagerAdapter
verwendet wird.
Als @ BlackHatSamurai im Kommentar erwähnt:
Dies funktioniert, weil
FragmentStatePagerAdapter
.__ zerstört. als Fragmente, die nicht verwendet werden.FragmentPagerAdapter
nicht.
Mit einem FragmentStatePagerAdapter
wurde mein Problem nicht vollständig behoben. Dies war ein ähnliches Problem, bei dem onCreateView
nicht für untergeordnete Fragmente im View-Pager aufgerufen wurde. Ich bin eigentlich Verschachtelung meiner FragmentPagerAdapter
in einer anderen Fragment
daher wurde die FragmentManager
für alle gemeinsam genutzt, so dass Instanzen der alten Fragmente erhalten bleiben. Das Update bestand darin, stattdessen eine Instanz von getChildFragmentManager
dem Konstruktor von FragmentPagerAdapter
in meinem Host-Fragment zuzuführen. So etwas wie...
FragmentPagerAdapter adapter = new FragmentPagerAdapter(getChildFragmentManager());
Die getChildFragmentManager()
-Methode ist über ein Fragment zugänglich und dies hat für mich funktioniert, weil sie ein privates FragmentManager
für dieses Fragment zurückgibt, speziell für Situationen, in denen Verschachtelungsfragmente erforderlich sind. Ich hoffe, das hilft jemandem, der vielleicht das gleiche Problem hat, das ich hatte !!
getChildFragmentManager()
verwendet werden muss. Ihre minimale API-Version muss mindestens 17 (4.2)
sein. Dies könnte einen Fehler in Ihre Zahnräder werfen. Wenn Sie Fragmente aus der Unterstützungsbibliothek v4 verwenden, sollten Sie dies natürlich tun.Es gibt zwei verschiedene Szenarien: 1.) Sie haben für jeden Pager dasselbe Layout: In diesem Fall ist es besser, wenn Sie Ihren benutzerdefinierten Adapter erweitern von PagerAdapter und geben Sie ein einzelnes Layout zurück.
2.) Sie haben für jeden Pager ein anderes Layout: In diesem Fall ist es besser, wenn Sie Ihren benutzerdefinierten Adapter erweitern von FragmentStatePagerAdapter und geben Sie für jeden Pager unterschiedliche Fragmets zurück.
long getItemId (int position)
überschreiben
FragmentPagerAdapter
speichert die mit getItem
erstellten Fragmente im Cache. Ich hatte das gleiche Problem - auch nachdem notifyDataSetChanged()
getItem
nicht aufgerufen wurde.
Dies ist eigentlich eine Funktion und kein Fehler. Sie müssen getItemId
überschreiben, damit Sie Ihre Fragmente korrekt wiederverwenden können. Da Sie Fragmente entfernen, ändern sich Ihre Positionen. Wie in den Dokumenten erwähnt:
long getItemId (int position)
Gibt eine eindeutige Kennung für den Artikel an der angegebenen Position zurück.
Die Standardimplementierung gibt die angegebene Position zurück. nterklassen sollten diese Methode außer Kraft setzen, wenn sich die Positionen von Elementen ändern können.
Geben Sie einfach eine eindeutige ID für jedes Fragment ein und Sie sind fertig.
Die Verwendung eines FragementStatePagerAdapter
oder die Rückgabe von POSITION_NONE
In int getItemPosition (Object object)
ist falsch. Sie werden kein Caching bekommen.
Ich habe getan, was @kanika und @ Jraco11 gepostet hatten, aber ich hatte immer noch das Problem.
Nach vielen Änderungen fand ich einen, der für mich funktionierte und meinem FragmentPagerAdapter den nächsten Code hinzugefügt hatte:
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
Entsprechend dem, was ich gelesen habe, wird getItemPosition verwendet, um den ViewPager zu benachrichtigen , ob ein Element aktualisiert werden soll oder nicht, und um Aktualisierungen zu vermeiden, wenn die Elemente an den sichtbaren Positionen nicht geändert wurden.
Ich fand, dass das Setzen eines Listeners im Tab-Layout den Aufruf verhinderte, wahrscheinlich, weil sie nur Platz für einen Listener in tabLayout.setOnTabSelectedListener
anstelle eines Arrays von Listenern haben.
die Methode getItem()
wird nur zum Erstellen neuer Elemente verwendet. Sobald sie erstellt wurden, wird diese Methode nicht mehr aufgerufen. Wenn Sie ein Element benötigen, das von einem Adapter verwendet wird, verwenden Sie diese Methode:
pagerAdapter.instantiateItem(viewPager, TAB_POS)