ViewPager с фрагментами - onPause (), onResume ()?

При использовании ViewPager с фрагментами наши методы onPause (), onResume () не вызываются при перемещении между вкладками. Есть ли какой-нибудь способ, которым мы можем выяснить фрагмент, когда нас делают видимыми или скрытыми?

К сожалению, у меня есть логика в onResume (), onPause (), например, регистрация в службах определения местоположения, которые никогда не останавливаются при переключении вкладок, потому что onPause () никогда не вызывается до тех пор, пока не выйдет все приложение.

Спасибо

Ответы на вопрос(6)

Вы можете использовать ниже метод вFragment

public void setUserVisibleHint(boolean isVisibleToUser){

}

когдаisVisibleToUser == trueфрагмент показан

Solution 1:

ОпределитьSparseArray в вашемViewPagers& APOS; адаптеры, как показано ниже. В этом массиве мы будем хранить экземпляр фрагментов.

SparseArray<Fragment> registeredFragments = new SparseArray<>();

А такжеOverride ваши адаптеры & apos;instantiateItem метод.

@Override
public Object instantiateItem(ViewGroup container, int position) {
    Fragment fragment = (Fragment) super.instantiateItem(container, position);
    registeredFragments.put(position, fragment);
    return fragment;
}

ТакжеOverride destroyItem метод вашегоViewPagers

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
    registeredFragments.remove(position);
    super.destroyItem(container, position, object);
}

И определите новый метод, чтобы получитьViewPager Fragments пример.

public Fragment getRegisteredFragment(int position) {
    return registeredFragments.get(position);
} 

Теперь вы можете реализовать свою логику сViewPager's OnPageChangeListener. Here's an example about how you can implement a viewpager's onPageChangeListener:

Определите целое число, чтобы сохранить текущую позицию:

int currentPos;

yourViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                // Empty method
            }

            @Override
            public void onPageSelected(int position) {
                  // This is paused fragment.
                  final Fragment pausedFragment = yourAdapter.getRegisteredFragment(currentPos);

                  // update current position value
                  currentPos = position;

                  // This is resumed fragment
                  final Fragment resumedFragment = yourAdapter.getRegisteredFragment(currentPos);
            }

            @Override
            public void onPageScrollStateChanged(int state) {
                // Empty method
            }
        });

Наконец, для восстановления состояния экземпляра обновите свою текущую позицию, чтобы она оставалась в курсе, в какой позиции пользователь оставилViewPager

currentPos = yourViewPager.getCurrentItem();

Solution 2:

Для другого решения вы можете найти свойViewPager Fragments отTag, Вы можете создать свой тег с помощью:

@NonNull
public static String generateViewPagerFragmentTag(int viewPagerId, int position) {
        final StringBuilder tagBuilder = new StringBuilder();
        tagBuilder.append("android:switcher:");
        tagBuilder.append(viewPagerId);
        tagBuilder.append(":");
        tagBuilder.append(position);
        return tagBuilder.toString();
    }

И найти свойFragment:

final Fragment yourFragment = getSupportFragmentManager().findFragmentByTag(generateViewPagerFragmentTag(R.id.your_viewpager, currentPos));

Edit: Несколько лет назад, когда я искал решение для получения текущего элемента ViewPager, который я пробовалUserVisibleHint вFragments и заметил, что это не надежно. Я не уверен, надежно ли это сейчас или нет, но все же я избегаю использовать.

Чтобы дать немного больше определения методам вsavepopulationответ:

yourPager.setOnPageChangeListener(new GridViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int row, int column, float rowOffset, float columnOffset, int rowOffsetPixels, int columnOffsetPixels) {

        }

        @Override
        public void onPageSelected(int row, int column) {
            // When on page selected if position is not specific for you
            // you can find your fragment or you can switch position.
        }

        @Override
        public void onPageScrollStateChanged(int state) {

        }
    });

Немного опоздал на вечеринку, но в моем текущем приложении я установил OffScreenPageLimit на 1 для моего окна просмотра, это означает, что фрагменты не кэшируются, и каждый раз, когда представление меняется, он перезагружает текущий фрагмент

https://developer.android.com/reference/android/support/v4/view/ViewPager.html#getOffscreenPageLimit ()

Учитывая то, что предыдущие решения не очень понятны, вот как я решил это благодаря Phix за его подсказку:

В обратном вызове OnPageChange ():

    Fragment old_fragment = getActiveFragment(old_position);
    Fragment new_fragment = getActiveFragment(new_position);
    old_f.setUserVisibleHint(false);
    old_f.onPause();
    new_f.setUserVisibleHint(true);
    new_f.onResume();

Затем в onResume ():

    if (getUserVisibleHint())
        /* resume code */

и в onPause ():

    if (!getUserVisibleHint())
        /* pause code */

Вот код getActiveFragment, позволяющий избежать его поиска:

    return fragmentManager.findFragmentByTag("android:switcher:" + viewPagerId + ":" + position);

NB. У фрагмента есть метод isVisible (), но он не выглядит очень последовательным, поэтому используется UserVisibleHint.

РЕДАКТИРОВАТЬ: заменить UserVisibleHint частным флагом. Работал намного лучше!

ViewPager поставляется сOnPageChangeListener интерфейс. Установив некоторые флаги для предыдущих и отображаемых в данный момент страниц, вы можете эмулировать это поведение.

Ваш ответ на вопрос