问题:ViewPager中的Fragment onResume()在片段实际可见之前被激发。

例如,我有2个带有ViewPager和FragmentPagerAdapter的片段。第二个片段仅对授权用户可用,我需要在片段可见时要求用户登录(使用警告对话框)。

但是,当第一个片段可见时,ViewPager创建第二个片段,以便缓存第二个碎片,并在用户开始滑动时使其可见。

因此,onResume()事件在第二个片段可见之前很久就被激发了。这就是为什么我试图找到一个事件,当第二个片段变得可见时,该事件会触发,以便在适当的时候显示对话框。

如何做到这一点?


当前回答

为此重写Fragment.onHiddenChanged()。

公共void onHiddenChanged(布尔隐藏)当片段的隐藏状态(由isHidden()返回)更改时调用。碎片开始时并不隐藏;每当片段从中改变状态时,都会调用此函数。参数hidden-boolean:如果片段现在隐藏,则为True,如果不可见,则为false。

其他回答

下面是使用onPageChangeListener的另一种方法:

  ViewPager pager = (ViewPager) findByViewId(R.id.viewpager);
  FragmentPagerAdapter adapter = new FragmentPageAdapter(getFragmentManager);
  pager.setAdapter(adapter);
  pager.setOnPageChangeListener(new OnPageChangeListener() {

  public void onPageSelected(int pageNumber) {
    // Just define a callback method in your fragment and call it like this! 
    adapter.getItem(pageNumber).imVisible();

  }

  public void onPageScrolled(int arg0, float arg1, int arg2) {
    // TODO Auto-generated method stub

  }

  public void onPageScrollStateChanged(int arg0) {
    // TODO Auto-generated method stub

  }
});

setUserVisibleHint(布尔可见)现在已弃用,因此这是正确的解决方案

FragmentPagerAdapter(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT)

在版本androidx.fragment:frage:1.1.0的ViewPager2和ViewPager中,您可以使用onPause()和onResume()来确定用户当前可以看到哪个片段。当片段可见时调用onResume(),当片段停止可见时调用onPause()。

要在第一个ViewPager中启用此行为,必须将FragmentPagerAdapter.behavior_RESUME_ONLY_CURRENT_FRAGMENT参数作为FragmentPagerAdapter构造函数的第二个参数传递。

重写FragmentPagerAdapter子类中的setPrimaryItem()。我用这个方法,而且效果很好。

@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
    // This is what calls setMenuVisibility() on the fragments
    super.setPrimaryItem(container, position, object);

    if (object instanceof MyWhizBangFragment) {
        MyWhizBangFragment fragment = (MyWhizBangFragment) object;
        fragment.doTheThingYouNeedToDoOnBecomingVisible();
    }
}

只有这对我有用!!而setUserVisibleHint(…)现在已被弃用(我在末尾附上了文档),这意味着大多数其他答案已被弃用;-)

public class FragmentFirewall extends Fragment {
    /**
     * Required cause "setMenuVisibility(...)" is not guaranteed to be
     * called after "onResume()" and/or "onCreateView(...)" method.
     */
    protected void didVisibilityChange() {
        Activity activity = getActivity();
        if (isResumed() && isMenuVisible()) {
            // Once resumed and menu is visible, at last
            // our Fragment is really visible to user.
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        didVisibilityChange();
    }

    @Override
    public void setMenuVisibility(boolean visible) {
        super.setMenuVisibility(visible);
        didVisibilityChange();
    }
}

已测试并与NaviagationDrawer一起使用,TheisMenuVisible()将始终返回true(onResume()似乎足够了,但我们也希望支持ViewPager)。

setUserVisibleHint已弃用。如果重写此方法,则传入true时实现的行为应移动到Fragment.onResume(),传入false时实现的操作应移动到Fragment.onPause()。

这似乎恢复了正常的onResume()行为。按下home键离开应用程序,然后重新进入应用程序,效果很好。onResume()不会连续调用两次。

@Override
public void setUserVisibleHint(boolean visible)
{
    super.setUserVisibleHint(visible);
    if (visible && isResumed())
    {
        //Only manually call onResume if fragment is already visible
        //Otherwise allow natural fragment lifecycle to call onResume
        onResume();
    }
}

@Override
public void onResume()
{
    super.onResume();
    if (!getUserVisibleHint())
    {
        return;
    }

    //INSERT CUSTOM CODE HERE
}