为什么切换fragment的时候会调用下一个页面的onResume周期方法?

stalker
  • 54

问题描述

如题 打开第一个页面的时候第二个页面的onResume事件就会触发 打开第二个页面的时候第三个页面的onResume就会触发 fragment的生命周期是onAttach()->onCreate()->onCreateView()->onActivityCreated()->onStart()->onResume() onResume不是应该显示以后可操作的状态时才应该触发的吗?

问题出现的环境背景及自己尝试过哪些方法

我猜测可能viewpager显示fragment的方式是不是同时显示3个 以防止打开下一页的时候出现卡顿?

相关代码

// 请把代码文本粘贴到下方(请勿用图片代替代码)
ViewPager viewPager = findViewById(R.id.viewPager);
viewPager.setCurrentItem(2);

你期待的结果是什么?实际看到的错误信息又是什么?

有没有方法让一个页面打开的时候才触发onResume事件?

回复
阅读 2.8k
3 个回答

我的猜测没错 在打开某一页的时候的确会提前实现下一页的所有生命周期 经过搜索发现真正处理页面显示的方法是setUserVisibleHint:

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        ....
    }

viewpager是有预加载机制,也就是下一个页面其实渲染完毕了

𝒁𝒉𝒋𝒍37
  • 2k
ViewPager有预加载机制,左右两侧的预加载页面数总是不小于1

如果想在用户可见时候加载,可以重写setUserVisibleHint(boolean)方法,但是需要注意的是,该函数的调用时机会导致你的App崩溃,因为它被调用的时候,并不保证视图都创建好了,可以查阅FragmentPagerAdapterFragmentStatePagerAdapter的源码便可知其中原因。因此,可以参考如下代码:

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (getView() != null) {
        ... ...
    }
}

另外需要注意的是,ViewPager中的第一个Fragment中的setUserVisibleHint(boolean)onActivityCreated(Bundle)onViewCreated(View, Bundle)都要早,因此,第一个(或者直接新建的)Fragment的处理和预加载的是不同的。优化代码如下:

/** 防止重入 */
private boolean mCreatedAndVisible = false;

public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    callWhenCreatedAndVisible();
}

public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (isVisibleToUser) {
        callWhenCreatedAndVisible();
    } else {
        mCreatedAndVisible = false;
    }
}

private void callWhenCreatedAndVisible(boolean useLooper) {
    if (!mCreatedAndVisible && getUserVisibleHint() && getView() != null) {
        mCreatedAndVisible = true;
        // TODO ...
    }
}

public void onDestroyView() {
    mCreatedAndVisible = false;
    super.onDestroyView();
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏