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


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

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

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

10 69

10 ответов:

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

посмотреть FragmentPagerAdapter javadoc онлайн и вы увидите, что есть метод setPrimaryItem (ViewGroup container, int position, Object object): void делаешь именно то, что вам нужно.

из javadoc

public void setPrimaryItem (ViewGroup container, int position, Object object)

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

параметры контейнер содержащий представление, из которого будет страница удаленный. расположите позицию страницы, которая теперь является основной. объект один и тот же объект, который был возвращен instantiateItem(посмотреть, int.)

обратите внимание на состояние прокрутки

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

Так что это может быть хорошей идеей, чтобы также прикрепить ViewPager.OnPageChangeListener и только делать то, что должно быть сделано, как только состояние прокрутки viewpagers становится 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() тоже помогает.

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

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

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

isVisible() 

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

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

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

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

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

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

Котлин:

if (userVisibleHint) {
    // the fragment is visible
} else {
    // the fragment is not visible
}

Java

if (getUserVisibleHint()) {
    // the fragment is visible
} else {
    // the fragment is not visible
}

https://developer.android.com/reference/android/app/Fragment.html#getUserVisibleHint()

https://stackoverflow.com/a/12523627/2069407