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

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

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

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

如何做到这一点?


当前回答

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

在ViewPager2的情况下,这是默认行为,但同样的行为可以很容易地为旧的好ViewPager启用。

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

FragmentPagerAdapter(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT)

注意:在android jetpack的新版本Fragment中,setUserVisibleHint()方法和带有一个参数的FragmentPagerAdapter构造函数现在已被弃用。

其他回答

我用了这个,它奏效了!

mContext.getWindow().getDecorView().isShown() //boolean

我发现只有在片段真正可见的情况下才调用onCreateOptionsMenu和onPrepareOptionsMenus方法。我找不到任何这样的方法,我也尝试了OnPageChangeListener,但它不适用于这种情况,例如,我需要在onCreate方法中初始化一个变量。

因此,这两种方法可以作为解决此问题的变通方法,特别适用于小而短的工作。

我认为,这是更好的解决方案,但不是最好的。我会使用这个,但同时等待更好的解决方案。

当做

一种简单的实现方法是在进入片段之前检查用户是否已登录。

在MainActivity中,您可以在onNavigationItemSelected方法中执行类似的操作。

 case R.id.nav_profile_side:


                if (User_is_logged_in) {

                    fragmentManager.beginTransaction()
                            .replace(R.id.content_frame
                                    , new FragmentProfile())
                            .commit();
                }else {

                    ShowLoginOrRegisterDialog(fragmentManager);

                }

                break;

然而,如果您使用的是导航抽屉,尽管我们没有转到ProfileFragment,但抽屉中的选择将更改为Profile。

要将选择重置为当前选择,请运行以下代码

        navigationView.getMenu().getItem(0).setChecked(true);

为此重写Fragment.onHiddenChanged()。

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

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