提问者:小点点

如何确定何时片段在ViewPager中变得可见


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

例如,我有两个带有ViewPagerFragmentPagerAdapter的片段。第二个片段仅对授权用户可用,并且我需要在片段变得可见时要求用户登录(使用警报对话框)。

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

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

如何才能做到这一点呢?


共3个答案

匿名用户

如何确定何时片段在ViewPager中变得可见

您可以通过重写片段中的SetUserVisibleHint来执行以下操作:

public class MyFragment extends Fragment {
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (isVisibleToUser) {
        }
        else {
        }
    }
}

匿名用户

更新:Android Support Library(rev 11)最终修复了用户可见提示问题,现在如果您使用Support Library for fragments,那么您可以安全地使用getUserVisibleHint()或者重写setUserVisibleHint()来捕获Gorn回答中描述的更改。

更新1这里是getUserVisibleHint()的一个小问题。默认情况下,该值为true

// Hint provided by the app that this fragment is currently visible to the user.
boolean mUserVisibleHint = true;

因此,当您尝试在调用SetUserVisibleHint()之前使用它时,可能会出现问题。作为解决办法,您可以在oncreate方法中设置值,如下所示。

public void onCreate(@Nullable Bundle savedInstanceState) {
    setUserVisibleHint(false);

过时的答案是:

在大多数用例中,ViewPager一次只显示一个页面,但是如果您正在使用Android Support Library pre-r11中的FragmentStatePagerAdapter,则预缓存的片段也会被置于“可见”状态(实际上是不可见的)。

我覆盖:

public class MyFragment extends Fragment {
    @Override
    public void setMenuVisibility(final boolean visible) {
        super.setMenuVisibility(visible);
        if (visible) {
            // ...
        }
    }
   // ...
}

捕获fragment的焦点状态,我认为这是您所说的“可见性”最合适的状态,因为ViewPager中只有一个fragment实际上可以将其菜单项与父activity的项放在一起。

匿名用户

这似乎恢复了您预期的正常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
}