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

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

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

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

Ответ 1

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

Посмотрите FragmentPagerAdapter javadoc онлайн, и вы увидите, что есть метод setPrimaryItem (контейнер ViewGroup, позиция int, объект Object): void делает именно то, что вам нужно.

Из javadoc

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

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

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

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

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

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

Ответ 2

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

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

Ответ 3

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

Ответ 4

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

Ответ 5

isVisible() 

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

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

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

Ответ 6

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

Ответ 7

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

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

Ответ 8

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

 @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();
        }
    }
}

Ответ 9

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

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