wake-up-neo.net

Das Fragment in ViewPager mit FragmentPagerAdapter ist beim zweiten Anzeigen leer

Ich habe eine Fragmentschnittstelle 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 anderes 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 drückt, um zur Liste zurückzukehren, und dann ein anderes Element auswählt. Beim zweiten Auswählen eines Elements wird anstelle des Viewpagers ein leerer Bildschirm angezeigt. In diesem Fall erhalte ich keine Fehler in meinem LogCat.

Warum erscheint der Viewpager nur beim ersten Mal?

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);
    }
}
90
howettl

Wir haben dies umgangen, indem wir die View-Pager-Elemente als Standardansichten und nicht als Fragmente implementiert und den Adapter entsprechend geändert haben.

2
howettl

Ich hatte das gleiche Problem. Das Ändern der übergeordneten Klasse meines PageAdapter von Android.support.v4.app.FragmentPagerAdapter in Android.support.v4.app.FragmentStatePagerAdapter löst mein ViewPager-Anzeigeproblem beim "zweiten Mal"!

210
Yann

Ich konnte dieses Problem lösen, indem ich getFragmentManager() durch getChildFragmentManager() im übergeordneten Fragment ersetzte. Dieses übergeordnete Fragment hat einen Android.support.v4.app.FragmentPagerAdapter instanziiert, um pageable (verschiebbare) Fragmente zu enthalten, was einen Fragmentmanager im Konstruktor erfordert. An diesen Konstruktor habe ich den Rückgabewert von getChildFragmentManager() übergeben.

hackbods Link war der Schlüssel ( https://developer.Android.com/about/versions/Android-4.2.html#NestedFragments ), der in diesem Beitrag gefunden wurde Fragmente in Fragmenten

Um ein Fragment zu verschachteln, rufen Sie einfach getChildFragmentManager() in der Fragment, in dem Sie ein Fragment hinzufügen möchten. Dies gibt ein .__ zurück. FragmentManager, den Sie wie gewohnt mit dem .__ verwenden können. Aktivität auf oberster Ebene zum Erstellen von Fragmenttransaktionen.

78
Daniel F

für mich musste ich das auf meinem viewpager anrufen:

myViewPager.setSaveFromParentEnabled(false);

Ich hatte das Problem, dass der Viewpager nicht erfrischend war und alles, was ich sah, ein leerer weißer Bildschirm war, auf dem die Fragmente sein sollten. Ich habe in getChildFragmentManager übergeben, aber es hat nicht geholfen. 

15
j2emanue

In meinem speziellen Fall, in dem ich ein CoordinatorLayout mit einem AppBarLayout und dem ViewPager verwendet habe, löste ich das , indem ich das Android entfernte: fitsSystemWindows = "true" aus meinen AppBarLayout-XML-Eigenschaften

Frag mich nicht warum. Ich weiß, es klingt ein bisschen lächerlich und es scheint, als hätte es keine Korrelation, aber es war diese einzige Zeile, die Probleme verursachte, da ich bereits getChildFragmentManager () in meinem Adapter verwendete. Ich habe einen ganzen Tag damit verbracht, meinen Code zu debuggen, nur um das herauszufinden. Ich hoffe, es erspart jemandem etwas Zeit.

8
emirua

Ich hatte das gleiche Problem, für das ich den Adapter von FragmentPagerAdapter in FragmentStatePagerAdapter und getFragmentManager() im übergeordneten Fragment in getChildFragmentManager() geändert habe. 

Der Grund dafür ist, dass FragmentStatePagerAdapter hilfreich ist, um eine große Anzahl von Seiten zu speichern, und der mit jeder besuchten Seite verknüpfte Speicher ist geringer, da nur der gespeicherte Zustand des Fragments beibehalten wird, während die Seite nicht sichtbar ist. Dies reduziert den Aufwand beim Wechseln zwischen den Fragmenten. 

7
Yashaswi N P

Das würde dir helfen.

    viewPager.setOffscreenPageLimit(position);
2
Pardeep Singh

Versuchen Sie, setOffscreenPageLimit (int limit) auf parent ViewPager zu setzen.

mViewPager.setOffscreenPageLimit(totalPages-1);

Das hat für mich wie Charme funktioniert.

In meinem Fall hatte ich Fragment in TabLayout mit ViewPager.

Und noch ein ViewPager in diesem Fragment. Das erste Mal klappte alles gut, aber wenn ich die Registerkarte wechsle und zurückkomme, wurde ein Teil meines Fragments leer.

0
Rumit Patel

Ich hatte das Gleiche, beim zweiten Aufruf des Pager-Adapters gibt die untergeordnete Ansicht eine NullPointerException zurück ... und das Ändern des Adapters in FragmentStatePagerAdapter löst auch mein Problem.

0
Arka-57

Ändern Sie FragmentPagerAdapter in FragmentStatePagerAdapter Verwenden Sie getChildFragmentManager() anstelle von getFragmentManager().

getChildFragmentManager() - weil laut Dokumentation ein privater FragmentManager zurückgegeben wird, um Fragmente in diesem Fragment zu platzieren und zu verwalten. Inzwischen wird getFragmentManager() den FragmentManager für die Interaktion mit Fragmenten zurückgeben, die dieser Aktivität zugeordnet sind

0
Mostafa Anter

Ich habe dieses Problem auf Xamarin Android beim zweiten Mal mit leerem Bildschirm erhalten.

viewPager.SaveFromParentEnabled = false;
0
Gerard

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.

@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);
    initViewPagerAdapter();
    return mView;
}
private void initViewPagerAdapter(){
    mAdapter = new ViewPagerAdapter(getFragmentManager(), cursor);
    new setAdapterTask().execute();
}

@Override
public void onResume(){
    super.onResume();
    initViewPagerAdapter();
}
0
Patrick