Как проверить, является ли вид фрагмента видимым для пользователя?

У меня есть ViewPager, каждая страница представляет собой фрагмент. Я хочу проверить, находится ли фрагмент в видимой области. Только тест Fragment.isVisible

  • Фрагмент привязан к активности
  • Фрагмент установлен на видимый
  • Фрагмент был добавлен в представление

ViewPager создаст 3 (по умолчанию) фрагмент, и все три из них соответствуют указанным выше критериям, но только один из них фактически отображается пользователю (человеческие глаза )

Solutions Collecting From Web of "Как проверить, является ли вид фрагмента видимым для пользователя?"

Вы правы, это лучший способ сделать это!

Взгляните на FragmentPagerAdapter javadoc онлайн, и вы увидите, что существует метод setPrimaryItem (контейнер ViewGroup, int position, Object object): void делает именно то, что вам нужно.

Из javadoc

Public void setPrimaryItem (контейнер ViewGroup, позиция int, объект Object)

Вызывается для информирования адаптера о том, какой элемент в данный момент считается «основным», то есть показ для пользователя как текущей страницы.

Параметры container Содержит View, из которого будет удалена страница. Position Позиция страницы, которая теперь является основной. Object Тот же объект, который был возвращен функцией instantiateItem (View, int).

Примечание о состоянии прокрутки

Теперь, если вы реализуете это и начинаете отладку, чтобы понять, когда именно это называется, вы быстро заметите, что это срабатывает несколько раз при подготовке фрагмента, и пока пользователь щелкает.

Поэтому неплохо было бы также подключить ViewPager.OnPageChangeListener и делать то, что должно быть сделано после того, как состояние прокрутки в рекурсиве снова станет SCOLL_STATE_IDLE .

Это то, что я использую для определения видимости фрагмента.

 private static boolean m_iAmVisible; @Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); m_iAmVisible = isVisibleToUser; if (m_iAmVisible) { Log.d(localTAG, "this fragment is now visible"); } else { Log.d(localTAG, "this fragment is now invisible"); } } 

Для моих целей он работал с ViewPager.OnPageChangeListener.onPageSelected() в сочетании с Fragment.onActivityCreated() для выполнения действия, когда фрагмент видим. Fragment.getUserVisibleHint() тоже помогает.

Что не так с использованием getView().isShown() чтобы выяснить, действительно ли фрагмент?

 isVisible() 

Может все еще вернуть true, даже если фрагмент находится за активностью.

Я использую следующее:

 if (getView() != null && getView().isShown()) { //your code here } 

Я использую метод setMenuVisibility -Method для решения этой проблемы. Поскольку каждый фрагмент может иметь элементы панели действий, это часть, в которой вы можете определить, какой фрагмент в данный момент отображается пользователю.

 @Override public void setMenuVisibility(final boolean visible) { super.setMenuVisibility(visible); if (!visible) { //not visible anymore }else{ yay visible to the user } } 

Если вы знаете, к какой «странице» прикреплен каждый фрагмент, вы можете использовать ViewPager.getCurrentItem (), чтобы определить, какой фрагмент «видимый».

В моем случае ia должны выполнить некоторую работу над первым фрагментом, когда фрагмент будет виден пользователю

  @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); if(viewPager.getAdapter() instanceof YourPager) { Fragment fragemnt=((YourPager)viewPager.getAdapter()).getFragment(0); //getFragment(int index) custom method if( fragemnt instanceof YourFragment) { ((YourFragment)fragemnt).methodWhochShouldBeCalledAfterUIVisible(); } } } 

setUserVisibleHint вероятно, не может быть вызван, onHiddenChanged может быть вызван не каждый раз, когда другой фрагмент закрывается. Таким образом, вы можете полагаться на onResumeonPause ), но его обычно называют слишком часто (например, при включении экрана устройства). Также в некоторых ситуациях он не вызывается, вы должны управлять текущим фрагментом в активности хоста и писать:

 if (currentFragment != null) { currentFragment.onResume(); }