Verhindert, dass ViewPager Off-Screen-Ansichten zerstört

Lesezeit: 4 Minuten

Ich habe einen ViewPager an einen FragmentPagerAdapter angeschlossen, der drei Fragmente anzeigt. Der ViewPager scheint die Ansicht eines gehosteten Fragments zu zerstören, wenn es mehr als eine Wischbewegung von der aktuellen Position entfernt ist.

Diese Ansichten sind alles einfache Listen und diese Optimierung ist völlig unnötig, daher würde ich sie gerne deaktivieren. Es verursacht einige visuelle Probleme, da auf die Listen Layoutanimationen angewendet wurden und diese Animationen wiedergegeben werden, nachdem sie zerstört und neu erstellt wurden. Es zeigt auch jedes Mal die Intro-Animation der Bildlaufleiste (bei der die Bildlaufleiste kurz sichtbar ist, um anzuzeigen, dass ein Bildlauf möglich ist), was ablenken kann, und die aktuelle Bildlaufposition des Benutzers geht dabei verloren.

Es lädt auch das dritte Fragment nicht, bis der erste Swipe erfolgt, was problematisch ist, da jedes Fragment seine eigenen Serviceaufrufe verarbeitet und ich es vorziehen würde, wenn alle drei gleichzeitig ausgelöst werden, wenn die Aktivität geladen wird. Eine Verzögerung des dritten Serviceanrufs ist alles andere als ideal.

Gibt es eine Möglichkeit, ViewPager davon zu überzeugen, dieses Verhalten zu stoppen und einfach alle meine Fragmente im Speicher zu behalten?

Benutzer-Avatar
David Snabel-Caunt

Im Überarbeitung 4 des Support Package wurde ViewPager eine Methode hinzugefügt, mit der Sie die Anzahl der zu verwendenden Offscreen-Seiten angeben können, anstatt der Standardeinstellung, die 1 ist.

In Ihrem Fall möchten Sie 2 angeben, damit die erste nicht zerstört wird, wenn Sie sich auf der dritten Seite befinden, und umgekehrt.

mViewPager = (ViewPager)findViewById(R.id.pager);
mViewPager.setOffscreenPageLimit(2);

  • Irgendeine Idee, wie man das auf einem Coverflow macht?

    – Josef

    16. August 2012 um 6:53 Uhr

  • Hallo. In dem, woran ich arbeite, werden die Fragmente/Seiten dynamisch erstellt, sodass es eine unbestimmte Anzahl wahrscheinlicher Fragmente gibt. In diesem Fall geht es normalerweise um 10 oder weniger. Wäre es nicht eine schlechte Speichernutzung, diese Lösung für so viele Seiten zu verwenden? Die Fragmente halten übrigens nur die Sicht. Vielen Dank!

    – Mahkie

    24. August 2012 um 0:13 Uhr

  • Diese Methode löst den Fehler „java.lang.IllegalStateException: Fragment bereits hinzugefügt:“ für meine App aus.

    – Alicanbatur

    18. Februar 2014 um 14:11 Uhr

  • Danke vielmals. Es hat einfach wirklich funktioniert. Ich hatte auch ein gleiches Problem wie @chefgon.

    – Prashant

    29. Juli 2015 um 10:09 Uhr

  • @mahie die obigen Lösungen, wenn für Dies wird als Optimierung angeboten. Wenn Sie im Voraus die Anzahl * der Seiten kennen, die Sie unterstützen müssen, oder Lazy-Loading-Mechanismen * auf Ihren Seiten haben, kann das Optimieren dieser Einstellung Vorteile in Bezug auf die wahrgenommene Glätte * von Paging-Animationen und Interaktionen haben. Wenn Sie eine kleine Anzahl von Seiten (3-4) * haben, die Sie alle gleichzeitig aktiv halten können, wird weniger Zeit mit dem Layout für * neu erstellte Ansichtsunterbäume verbracht, da der Benutzer hin und her blättert

    – Asthma

    14. Januar 2016 um 15:27 Uhr

Standardmäßig erstellt ViewPager die Fragmente neu, wenn Sie über die Seite wischen. Um dies zu verhindern, können Sie eines von zwei Dingen versuchen:

1. Rufen Sie in onCreate() Ihrer Fragmente setRetainInstance(true) auf.

2. Wenn die Anzahl der Fragmente fest und relativ klein ist, fügen Sie in Ihrem onCreate() den folgenden Code hinzu:

ViewPager mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setOffscreenPageLimit(3);

Wenn ich mich recht erinnere, ist die zweite Option erfolgversprechender. Aber ich fordere Sie auf, beide auszuprobieren und zu sehen, welche von ihnen funktionieren.

“Legen Sie die Anzahl der Seiten fest, die auf beiden Seiten der aktuellen Seite in der Ansichtshierarchie im Ruhezustand beibehalten werden sollen. Seiten, die dieses Limit überschreiten, werden bei Bedarf vom Adapter neu erstellt.”

http://developer.android.com/reference/android/support/v4/view/ViewPager.html#setOffscreenPageLimit(int)

Die ausgewählte Antwort ist gut, war aber nicht wirklich gut für mich. Dies liegt daran, dass ich viele Fragmente hatte (20-30) und daher die Aktivität mit dem ViewPager viel Zeit zum Laden benötigt hätte, wenn ich setOffscreenPageLimit(30) verwendet hätte. In meinem Fall musste ich die Methode destroyItem() (in der Adapter-Klasse des ViewPagers) implementieren und den Aufruf der super-Funktion entfernen. Hier ist der Pseudocode

@Override                                                                                    
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
                                                                                             
}                                                                                            

Wenn Sie jetzt mehr Kontext möchten, finden Sie hier die gesamte ViewPagerAdapter-Klasse

public class ViewPagerAdapter extends FragmentPagerAdapter {
    private final List<Fragment> listFragment =
            new ArrayList<>();
    public ViewPagerAdapter(@NonNull FragmentManager fm) {
        super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
    }

    @NonNull
    @Override
    public Fragment getItem(int position) {
        return listFragment.get(position);
    }

    @Override
    public int getCount() {
        return listFragment.size();
    }

    /*This is the method I was taking about*/
    @Override
    public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
    
    }

    public void addFragment(Fragment fragment)
    {
        listFragment.add(fragment);
        notifyDataSetChanged();
    }
}

1338240cookie-checkVerhindert, dass ViewPager Off-Screen-Ansichten zerstört

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy