wake-up-neo.net

FragmentPagerAdapter getItem wird nicht aufgerufen

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)); 
108
Kanika

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 FragmentPagerAdapterFragmentStatePagerAdapter verwendet wird.

Als @ BlackHatSamurai im Kommentar erwähnt:

Dies funktioniert, weil FragmentStatePagerAdapter .__ zerstört. als Fragmente, die nicht verwendet werden. FragmentPagerAdapter nicht.

280
Kanika

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 !!

  • Denken Sie jedoch daran, dass 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.
141
Jraco11

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.

2
Maddy

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.

2
vedant

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. 

2
Jorge Casariego

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.

0
Oliver Dixon

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)
0
B-GangsteR