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

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

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

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

如何做到这一点?


当前回答

可能很晚了。这对我很有用。我稍微更新了@Gobar和@kris解决方案的代码。我们必须更新PagerAdapter中的代码。

每当选项卡可见并返回其位置时,都会调用setPrimaryItem。如果位置相同,意味着我们不动。如果位置已更改且当前位置不是我们单击的选项卡设置为-1。

private int mCurrentPosition = -1;

@Override
public void setPrimaryItem(@NotNull ViewGroup container, int position, @NotNull Object object) {
    // This is what calls setMenuVisibility() on the fragments
    super.setPrimaryItem(container, position, object);
    if (position == mCurrentPosition) {
        return;
    }
    if (object instanceof YourFragment) {
        YourFragment fragment = (YourFragment) object;
        if (fragment.isResumed()) {
            mCurrentPosition = position;
            fragment.doYourWork();//Update your function
        }
    } else {
        mCurrentPosition = -1;
    }
}

其他回答

在片段中添加以下代码

@Override
public void setMenuVisibility(final boolean visible) 
 {
    super.setMenuVisibility(visible);
    if (visible && isResumed()) 
     {

     }
}

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

您可以通过覆盖片段中的setUserVisibleHint来执行以下操作:

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

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

在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);

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

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

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

当做

当视图寻呼机中的片段显示在屏幕上供用户查看时,我试图启动计时器时遇到了这个问题。

计时器总是在用户看到片段之前启动。这是因为片段中的onResume()方法在我们看到片段之前被调用。

我的解决方案是检查onResume()方法。当片段8是视图页面的当前片段时,我想调用某个方法“foo()”。

@Override
public void onResume() {
    super.onResume();
    if(viewPager.getCurrentItem() == 8){
        foo();
        //Your code here. Executed when fragment is seen by user.
    }
}

希望这有帮助。我经常看到这个问题。这似乎是我见过的最简单的解决方案。其他很多都与较低的API等不兼容。