it-swarm.com.ru

Просмотр пейджера и фрагмента жизненного цикла

У меня есть ViewPager, который загружает три страницы одновременно. Если я проведу пальцем со страницы 1 на страницу 2, затем на 3, первая страница (фрагмент) перейдет к onPause(). Затем, если я проведу пальцем по второй странице, 1-я страница перейдет к onResume(), хотя страница 1 все еще не видна пользователю. Итак, мой вопрос: как отличить первую и вторую страницу в коде? Например, если мне нужно запустить фрагмент кода, когда фрагмент виден, как это сделать?

31
shreyas

FragmentPagerAdapter сохраняет дополнительные фрагменты, кроме показанного, в возобновленном состоянии. Решение заключается в реализации пользовательского OnPageChangeListener и создании нового метода для отображения фрагмента.

1) Создание интерфейса LifecycleManager Интерфейс будет иметь два метода, и каждый фрагмент ViewPager будет реализовывать его. Эти методы заключаются в следующем:

public interface FragmentLifecycle {

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

}

2) Пусть каждый Fragment реализует интерфейс Add iplements для каждого объявления класса:

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

3) Реализовать интерфейсные методы в каждом фрагменте. Чтобы убедиться, что он действительно работает как положено, я просто запишу вызов метода и покажу 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) Вызовите методы интерфейса при изменении страницы ViewPager. Вы можете установить OnPageChangeListener для ViewPager и получать обратный вызов каждый раз, когда ViewPager показывает другую страницу:

pager.setOnPageChangeListener(pageChangeListener);

5) Реализуйте OnPageChangeListener для вызова ваших пользовательских методов жизненного цикла

Слушатель знает новую позицию и может вызвать интерфейсный метод для нового фрагмента с помощью PagerAdapter. Я могу здесь вызвать onResumeFragment () для нового фрагмента и onPauseFragment () для текущего.

Мне нужно также сохранить текущую позицию фрагмента (изначально текущая позиция равна 0), так как я не знаю, прокручивал ли пользователь слева направо или справа налево. Посмотрите, что я имею в виду в коде:

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) { }
};

Я не писал код. Полный учебник здесь: http://looksok.wordpress.com/2013/11/02/viewpager-with-detailed-fragment-lifecycle-onresumefragment-inclusion-source-code/

34
Shreyas Shetty

если ваш Фрагмент расширяет Android.support.v4.app.Fragment

вы можете использовать это, это работает для меня. 

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

Переопределить setUserVisibleHint(). Этот метод будет вызываться, как только фрагмент будет виден пользователю.

2
Parin Parikh

пользовательский метод pager.setOffscreenPageLimit (число), чтобы установить, сколько фрагментов вы хотите сохранить в стеке. 

1
jack

Решите вашу проблему:

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

Override setUserVisibleHint () это будет вызываться, когда фрагмент виден пользователю

0
venu46