本文主要是讲解迁移到AndroidX之后,对原本的ViewPager懒加载造成的影响,和如何进行优化。参考的项目来自
最后的代码修改对比也是来自大神的文章,建议先看一下再过来看本文
一、为什么要迁移为AndroidX
根据官方说明,AndroidX是对原始Android支持库(android.support.*)进行了重大改进和统一管理,旧的库依然能用,但是新库的开发都将会在AndroidX中进行,所以建议还是迁移到AndroidX。
根据注释可以知道
当behavior == BEHAVIOR_SET_USER_VISIBLE_HINT 时,Fragment切换时,会触发setUserVisibleHint。
这个效果和
的效果一样,也就是说,如果你不想修改原来懒加载的逻辑,只需要这么写
FragmentPagerAdapter adapter = new FragmentPagerAdapter(fm);
FragmentPagerAdapter adapter = new FragmentPagerAdapter(fm, BEHAVIOR_SET_USER_VISIBLE_HINT);
但是,我们看到了BEHAVIOR_SET_USER_VISIBLE_HINT也被标识了@Deprecated (废弃),建议我们使用BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT。所以初始化方式是:
FragmentPagerAdapter adapter = new FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
而这时候会用到生命周期状态标识Lifecycle.State。
2 FragmentPageAdapter初始化Fragment
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
//...省略非重点代码
if (mBehavior == BEHAVIOR_SET_USER_VISIBLE_HINT) {
//旧版本,触发setUserVisibleHint
fragment.setUserVisibleHint(false);
mFragments.set(position, fragment);
//关键句,添加Fragment进入事物list
mCurTransaction.add(container.getId(), fragment);
if (mBehavior == BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
//AndroidX,设置初始化执行到onStart()就停止了
mCurTransaction.setMaxLifecycle(fragment, Lifecycle.State.STARTED);
return fragment;
追踪进入mCurTransaction.add(container.getId(), fragment);方法
void doAddOp(int containerViewId, Fragment fragment, @Nullable String tag, int opcmd) {
//...省略非重点代码
addOp(new Op(opcmd, fragment));
//初始化执行到onResume()
this.mOldMaxState = Lifecycle.State.RESUMED;
this.mCurrentMaxState = Lifecycle.State.RESUMED;
到这里,我们就能明白了如果是旧版本,Fragment初始化的时候,默认会执行到onResume(),而AndroidX只会执行到onStart(),所以我们迁移到AndroidX之后,不需要全都依靠setUserVisibleHint()来判断当前页面是否显示,我们可以根据onResume()来判断。
3 迁移到AndroidX之后,BaseFragment相应的修改
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
mRoot = inflater.inflate(getLayoutId(), container, false);
Log.d(getLifeCycleTag(), "onCreateView");
initView(mRoot);
//在View创建完毕之后,isViewCreate 要变为true
isViewCreated = true;
//下面2段代码可以删除
//if (!isHidden() && getUserVisibleHint())
//dispatchVisibleState(true);
return mRoot;
@Override
public void onResume() {
super.onResume();
Log.d(getLifeCycleTag(), "onResume");
/* 旧版本
if (!isFirstVisible) {
if (!isHidden() && !currentVisibleState && getUserVisibleHint())
dispatchVisibleState(true);
//新版本
if (!isHidden() && !currentVisibleState && isResumed()) {
dispatchVisibleState(true);
@Override
public void onPause() {
MobclickAgent.onPageEnd(this.getClass().getName());
super.onPause();
Log.d(tag,"onPause: ");
/* 旧版本
if (currentVisibleState && !isResumed()) {
dispatchVisibleState(false);
//新版本
if (currentVisibleState && !isResumed()) {
dispatchVisibleState(false);
//其他不需要更改