Android Fragment懒加载新思路

简介: 在Android x以前,我们实现懒加载通常是通过 setUserVisibleHint 方法来控制Fragment是否可见。在Android x之后,Google 提供了新的方案给我们。今天我们就来学习一下。

在Android x以前,我们实现懒加载通常是通过 setUserVisibleHint 方法来控制Fragment是否可见。在Android x之后,Google 提供了新的方案给我们。今天我们就来学习一下。

如果在Android x中直接使用以前的方案,会提示如下,方法已过时:


网络异常,图片无法展示
|


点进去查看注释:



大概就是这个方法可以告诉当前Fragment的是否对用户可见,但是可以在生命周期外调用,所以生命周期的方法回调可能不是很准确。所以在Android x里面,Google推荐我们使用 setMaxLifecycle.

我们点进去看一下这个方法:

/**
 * Set a ceiling for the state of an active fragment in this FragmentManager. If fragment is
 * already above the received state, it will be forced down to the correct state.
 *
 * <p>The fragment provided must currently be added to the FragmentManager to have it's
 * Lifecycle state capped, or previously added as part of this transaction. The
 * {@link Lifecycle.State} passed in must at least be {@link Lifecycle.State#CREATED}, otherwise
 * an {@link IllegalArgumentException} will be thrown.</p>
 *
 * @param fragment the fragment to have it's state capped.
 * @param state the ceiling state for the fragment.
 * @return the same FragmentTransaction instance
 */
@NonNull
public FragmentTransaction setMaxLifecycle(@NonNull Fragment fragment,
        @NonNull Lifecycle.State state) {
    addOp(new Op(OP_SET_MAX_LIFECYCLE, fragment, state));
    return this;
}

通过这个方法,我们可以设置Fragment的生命周期上限,也就是你可以设置这个Fragment最大生命周期限制,如果生命周期执行超过了设置的片段,则会强制降至正确的生命周期。而且传入的生命周期最低限制必须是 Create,也就是执行到了onCreateView。

一共提供了如下几种状态:



下面我们用一个Demo演示一下:

xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/fragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.cloud.fragment.TestActivity">
</FrameLayout>

Activity:

  @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        StatusBarUtil.setTranSparentBar(this);
        setContentView(R.layout.activity_test);
        Fragment1 fragment1 = Fragment1.newInstance();
        getSupportFragmentManager()
                .beginTransaction()
                .replace(R.id.fragment, fragment1)
                .setMaxLifecycle(fragment1, Lifecycle.State.CREATED)
                .commit();
    }

Fragment1

public class Fragment1 extends BaseFragment {
    ....
    @Override
    public void onCreate() {
        super.onCreate();
        Log.e("demo", "f1-onStart");
    }
}

上面的代码都很简单,不必要的地方就省略了,主要是 setMaxLifecycle 的使用地方注意即可:


运行我们的模拟器:


网络异常,图片无法展示
|


因为没有执行到onResume,所以我们的界面无法看到.

log如下:


网络异常,图片无法展示
|


此时更改 为 Resume.

   getSupportFragmentManager()
                .beginTransaction()
                .add(R.id.fragment, fragment1)
                .setMaxLifecycle(fragment1, Lifecycle.State.RESUMED)
                .commit();

网络异常,图片无法展示
|


日志如下:


网络异常,图片无法展示
|


效果如上,使用的方法也没有什么说的了。

其余的几个也不用太说了,都差不多。

现在我们来看一下 懒加载 的新方案:

我们先查看一下 FragmentPagerAdapter 类:


网络异常,图片无法展示
|


新增了一个参数,这个参数用来控制选用哪种模式,现在提供了两种模式,如下:

其中,默认使用的是 BEHAVIOR_SET_USER_VISIBLE_HINT,至于它们是干什么的,我们具体继续往下看:当然结合我们开始时的Demo,从注释中也能看出端倪。



因为Android x废除了 setUserVisibleHint() 方法,所以相应的适配器也进行了改动:



这里可以看到,上面新增的那两个参数用到了这里。

我们来看里面的逻辑,默认会使用 Lifecycle.State.RESUMED,也就是说默认会执行生命周期方法到onResume,并且代替了 setUserVisibleHint(true) 方法,而它的作用是用来通知 当前Fragment 是否对用户可见。然后用 BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT 代替了 setUserVisibleHint(false)。

从而默认的FragmentPagerAdapter构造方法会使Fragment 执行到 onResume,而指定了 构造参数BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT 的,则只会执行到 onStart。

有了这个特性,我们来试试新的懒加载方案:


demo也很简单,只需要new FragmentAdapter时,传入BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT即可。

new FragmentAdapter(getSupportFragmentManager(),FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT,list)

具体的代码就不用演示了。


下面我们通过log看一下日志变化。


测试demo:ViewPager-Fragment1-Fragment2


打开Activity时:


网络异常,图片无法展示
|


当切换到第二个Fragment时:



可以观察到每次都会执行onResume,所以我们可以将我们的数据加载方法放在 onResume中。简单的Demo如下:

public abstract class BaseFragment extends Fragment {
    private View view;
    public abstract int setView();
    public abstract void initView();
    public abstract void initData();
    private volatile boolean onVisible = false;
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        view = inflater.inflate(setView(), null);
        onVisible = true;
        initView();
        return view;
    }
    @Override
    public void onResume() {
        super.onResume();
        //
        if (onVisible) {
            initData();
            onVisible = false;
        }
        updateData();
    }
   @Override
    public void onPause() {
        super.onPause();
        //  
    }
    private void updateData() {
    }
    public View getView() {
        return view;
    }
}

所以我们具体的操作就可以放到 onResume和onPause中,分别对应可见或不可见,很简单。

好了,如果有帮到你的地方,不胜荣幸。如果有什么疑问或者问题,也欢迎大家留言学习。

目录
相关文章
|
存储 Ubuntu Linux
Docker(四)进阶:Docker镜像概述和分层原理
镜像是一个只读模板,带有创建Docker容器的说明。通常,一个镜像基于另一个镜像,并带有一些额外的定制。例如,您可以构建一个基于ubuntu镜像的镜像,但是要安装Apache web服务器和您的应用程序,以及运行应用程序所需的配置细节。
2820 0
Docker(四)进阶:Docker镜像概述和分层原理
|
人工智能 监控 安全
数字化矿山---推动矿山行业数字化转型
数字化矿山通过AI、物联网等技术推动矿业转型,实现生产可视化、管理智能化,构建三维地质模型与七大监测系统,提升安全、环保与效率,助力行业可持续发展。
Junit4中的新断言assertThat的使用方法
Junit4中的新断言assertThat的使用方法
532 0
|
Android开发 数据格式 XML
|
编解码 Android开发 开发者
dp(相对大小) 和 px(像素)之间的相互转换
dp(相对大小) 和 px(像素)之间的相互转换
558 4
|
Java C++
AIDL与HIDL核心概念
AIDL与HIDL核心概念
647 0
|
Android开发
Android系统自带样式(android:theme)解析
做Android开发时经常会修改系统默认的主题样式,在android的sdk  安装目录data\res\values\themes.
2946 0
|
Android开发 开发者
Android UI设计: 请解释Activity的Theme是什么,如何更改应用程序的主题?
Android UI设计: 请解释Activity的Theme是什么,如何更改应用程序的主题?
730 1
|
存储 缓存 Java
|
XML Android开发 数据格式
Android 弹性布局 FlexboxLayout了解一下
原文链接:https://mp.weixin.qq.com/s/Mi3cK7xujmEMI_rc51-r4g RelativeLayout、LinearLayout等常用布局相信大家早已耳熟能详,今天给大家介绍一款新的布局方式「弹性布局」--FlexboxLayout。
1898 0

热门文章

最新文章