it-swarm.com.de

Anzeigen des Lebenszyklus von Pager und Fragmenten

Ich habe einen ViewPager, der jeweils drei Seiten lädt. Wenn ich von Seite 1 zu Seite 2 und dann zu 3 wische, wechselt die erste Seite (Fragment) zu onPause(). Wenn ich dann zur zweiten Seite wische, erscheint die erste Seite in onResume(), obwohl die Seite 1 für den Benutzer immer noch nicht sichtbar ist. Meine Frage ist also: Wie unterscheidet man die erste und die zweite Seite im Code? Wenn ich zum Beispiel einen Code ausführen muss, wenn das Fragment sichtbar ist, wie wird das gemacht?

31
shreyas

Der FragmentPagerAdapter hält neben dem angezeigten Fragment weitere Fragmente im wiederaufgenommenen Zustand. Die Lösung besteht darin, einen benutzerdefinierten OnPageChangeListener zu implementieren und eine neue Methode zu erstellen, wenn das Fragment angezeigt wird.

1) LifecycleManager-Schnittstelle erstellen Die Schnittstelle verfügt über zwei Methoden, die von jedem ViewPager-Fragment implementiert werden. Diese Methoden sind wie folgt:

public interface FragmentLifecycle {

    public void onPauseFragment();
    public void onResumeFragment();

}

2) Lassen Sie für jedes Fragment die Schnittstelle Iplements-Anweisung für jede Klassendeklaration implementieren:

public class FragmentBlue extends Fragment implements FragmentLifecycle
public class FragmentGreen extends Fragment implements FragmentLifecycle
public class FragmentPink extends Fragment implements FragmentLifecycle

3) Schnittstellenmethoden in jedem Fragment implementieren Um zu überprüfen, ob es wirklich wie erwartet funktioniert, protokolliere ich nur den Methodenaufruf und zeige Toast:

@Override
public void onPauseFragment() {
    Log.i(TAG, "onPauseFragment()");
    Toast.makeText(getActivity(), "onPauseFragment():" + TAG, Toast.LENGTH_SHORT).show(); 
}

@Override
public void onResumeFragment() {
    Log.i(TAG, "onResumeFragment()");
    Toast.makeText(getActivity(), "onResumeFragment():" + TAG, Toast.LENGTH_SHORT).show(); 
}

4) Aufrufschnittstellenmethoden bei ViewPager-Seitenwechsel Sie können OnPageChangeListener für ViewPager festlegen und jedes Mal einen Rückruf erhalten, wenn ViewPager eine andere Seite anzeigt:

pager.setOnPageChangeListener(pageChangeListener);

5) Implementieren Sie OnPageChangeListener, um Ihre benutzerdefinierten Lifecycle-Methoden aufzurufen

Listener kennt die neue Position und kann die Interface-Methode mit Hilfe von PagerAdapter auf dem neuen Fragment aufrufen. Ich kann hier onResumeFragment () für neues Fragment und onPauseFragment () für das aktuelle Fragment aufrufen.

Ich muss auch die aktuelle Position des Fragments speichern (anfangs ist die aktuelle Position gleich 0), da ich nicht weiß, ob der Benutzer von links nach rechts oder von rechts nach links gescrollt hat. Sehen Sie, was ich im Code meine:

private OnPageChangeListener pageChangeListener = new OnPageChangeListener() {

    int currentPosition = 0;

    @Override
    public void onPageSelected(int newPosition) {

        FragmentLifecycle fragmentToShow = (FragmentLifecycle)pageAdapter.getItem(newPosition);
        fragmentToShow.onResumeFragment();

        FragmentLifecycle fragmentToHide = (FragmentLifecycle)pageAdapter.getItem(currentPosition);
        fragmentToHide.onPauseFragment();

        currentPosition = newPosition;
    }

    @Override
    public void onPageScrolled(int arg0, float arg1, int arg2) { }

    public void onPageScrollStateChanged(int arg0) { }
};

Ich habe den Code nicht geschrieben. Vollständiges Tutorial hier: http://looksok.wordpress.com/2013/11/02/viewpager-mit-detailed-fragment-lifecycle-onresumefragment-inklusive-source-code/

34
Shreyas Shetty

wenn Ihr Fragment Android.support.v4.app.Fragment erweitert

sie können dies verwenden, es funktioniert für mich. 

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (!isVisibleToUser) {
        //do sth..
    }
}
7
Hao Qi

Überschreiben Sie setUserVisibleHint(). Diese Methode wird aufgerufen, sobald das Fragment für den Benutzer sichtbar ist.

2
Parin Parikh

benutzermethode pager.setOffscreenPageLimit (number), um festzulegen, wie viele Fragmente im Stapel enthalten sein sollen. 

1
jack

Lösen Sie Ihr Problem:

public class FragmentVisibleHelper implements LifecycleObserver {

    private static final String TAG = "VipVisibleHelper";

    public interface IVisibleListener {

        void onVisible();

        void onInVisible();
    }

    boolean mIsVisibleToUser;
    boolean mStarted = false;

    volatile boolean mIsCalledVisible = false;
    volatile boolean mIsCalledInvisible = false;


    IVisibleListener mListener;

    public void setListener(IVisibleListener mListener) {
        this.mListener = mListener;
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    void onResume() {
        Log.d(TAG, String.format("%-60s %s", this.toString(), "onResume() called:"));
        if (mIsVisibleToUser) {
            dispatchVisible();
        }
    }

    private void dispatchVisible() {
        Log.d(TAG, String.format("%-60s %s", this.toString(), "dispatchVisible() called mIsCalledVisible = [" + mIsCalledVisible + "] mIsCalledInvisible = [" + mIsCalledInvisible + "] "));
        if (!mIsCalledVisible) {
            mIsCalledVisible = true;
            mIsCalledInvisible = false;

            if (Profile.LOG) {
                Log.d(TAG, String.format("%-60s %s", this.toString(), "dispatchVisible() called onVisible"));
            }

            if (mListener != null) {
                mListener.onVisible();
            }
        }
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    void onPause() {
        Log.d(TAG, String.format("%-60s %s", this.toString(), "onPause() called:"));
        if (mIsVisibleToUser) {
            dispatchInvisible();
        }
    }

    private void dispatchInvisible() {
        Log.d(TAG, String.format("%-60s %s", this.toString(), "dispatchInvisible() called mIsCalledVisible = [" + mIsCalledVisible + "] mIsCalledInvisible = [" + mIsCalledInvisible + "] "));
        if (!mIsCalledInvisible) {
            mIsCalledInvisible = true;
            mIsCalledVisible = false;

            if (Profile.LOG) {
                Log.d(TAG, String.format("%-60s %s", this.toString(), "dispatchInvisible() called onInVisible"));
            }

            if (mListener != null) {
                mListener.onInVisible();
            }
        }
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    void onStart() {
        Log.d(TAG, String.format("%-60s %s", this.toString(), "onStart() called"));
        mStarted = true;
        if (mIsVisibleToUser) {
            dispatchVisible();
        }
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    void onStop() {
        Log.d(TAG, String.format("%-60s %s", this.toString(), "onStop() called"));
        if (mIsVisibleToUser) {
            dispatchInvisible();
        }
        mStarted = false;
    }

    public void setUserVisibleHint(boolean isVisibleToUser) {
        Log.d(TAG, String.format("%-60s %s", this.toString(), "setUserVisibleHint() called with: isVisibleToUser = [" + isVisibleToUser + "]:"));
        mIsVisibleToUser = isVisibleToUser;
        if (mStarted) { // fragment have created
            if (mIsVisibleToUser) {
                dispatchVisible();
            } else {
                dispatchInvisible();
            }
        }
    }

    public boolean isVisibleToUser() {
        return mIsVisibleToUser;
    }
}
0
biezhihua

Überschreiben Sie setUserVisibleHint () Dies wird aufgerufen, wenn fragment für den Benutzer sichtbar ist

0
venu46