相关文章推荐
博学的双杠  ·  《国家突发事件总体应急预案》新旧版本对比-西 ...·  11 月前    · 
性感的伤疤  ·  文博日历丨楚国人的“钢镚儿”长得好囧啊_新闻 ...·  1 年前    · 
风流的爆米花  ·  贵州省生态环境厅2023年10月拟作出的贵州 ...·  1 年前    · 
慷慨大方的镜子  ·  斗罗之开局获得剑神传承 - 抖音·  2 年前    · 
风流倜傥的松鼠  ·  生物医学跨学科研究中心-北京大学前沿交叉学科研究院·  3 年前    · 
Code  ›  Android Fragment懒加载新思路开发者社区
懒加载 fragment切换
https://cloud.tencent.com/developer/article/1941169
怕老婆的匕首
1 年前
Petterp

Android Fragment懒加载新思路

前往小程序,Get 更优 阅读体验!
立即前往
腾讯云
开发者社区
文档 建议反馈 控制台
首页
学习
活动
专区
工具
TVP
最新优惠活动
文章/答案/技术大牛
发布
首页
学习
活动
专区
工具
TVP 最新优惠活动
返回腾讯云官网
Petterp
首页
学习
活动
专区
工具
TVP 最新优惠活动
返回腾讯云官网
社区首页 > 专栏 > Android Fragment懒加载新思路

Android Fragment懒加载新思路

作者头像
Petterp
发布 于 2022-02-09 13:11:46
573 0
发布 于 2022-02-09 13:11:46
举报
文章被收录于专栏: JetPack

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

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

image-20191203220602868
image-20191203220602868

点进去查看注释:

image-20191203221003196
image-20191203221003196

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

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

代码语言: javascript
复制
/**
 * 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。

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

image-20191203221942620
image-20191203221942620

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

xml

代码语言: javascript
复制
<?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:

代码语言: javascript
复制
  @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

代码语言: javascript
复制
public class Fragment1 extends BaseFragment {
    @Override
    public void onCreate() {
        super.onCreate();
        Log.e("demo", "f1-onStart");
}

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

运行我们的模拟器:

image-20191203223510187
image-20191203223510187

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

log如下:

image-20191203224301513
image-20191203224301513

此时更改 为 Resume .

代码语言: javascript
复制
   getSupportFragmentManager()
                .beginTransaction()
                .add(R.id.fragment, fragment1)
                .setMaxLifecycle(fragment1, Lifecycle.State.RESUMED)
                .commit();
image-20191203223934927
image-20191203223934927

日志如下:

image-20191203224341578
image-20191203224341578

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

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

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

我们先查看一下 FragmentPagerAdapter 类:

image-20191203234946009
image-20191203234946009

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

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

image-20191203235121500
image-20191203235121500

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

image-20191203234030654
image-20191203234030654

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

我们来看里面的逻辑,默认会使用 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 即可。

代码语言: javascript
复制
new FragmentAdapter(getSupportFragmentManager(),FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT,list)

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

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

测试demo:ViewPager-Fragment1-Fragment2

打开Activity时:

image-20191204001154967
image-20191204001154967

当切换到第二个Fragment时:

image-20191204001225348
image-20191204001225348

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

代码语言: javascript
复制
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() {
 
推荐文章
博学的双杠  ·  《国家突发事件总体应急预案》新旧版本对比-西北大学公共管理学院
11 月前
性感的伤疤  ·  文博日历丨楚国人的“钢镚儿”长得好囧啊_新闻频道_央视网(cctv.com)
1 年前
风流的爆米花  ·  贵州省生态环境厅2023年10月拟作出的贵州金元威宁300MW/600MWh独立共享储能电站项目环境影响评价表审批意见的公示(核与辐射)
1 年前
慷慨大方的镜子  ·  斗罗之开局获得剑神传承 - 抖音
2 年前
风流倜傥的松鼠  ·  生物医学跨学科研究中心-北京大学前沿交叉学科研究院
3 年前
今天看啥   ·   Py中国   ·   codingpro   ·   小百科   ·   link之家   ·   卧龙AI搜索
删除内容请联系邮箱 2879853325@qq.com
Code - 代码工具平台
© 2024 ~ 沪ICP备11025650号