android 监听adapter 更新完成_ViewPager2重大更新,支持offscreenPageLimit

本文作者

作者:HitenDev

链接:

https://juejin.im/post/5cda3964f265da035d0c9d8f

本文由作者授权发布。

1 前言

最近ViewPager2发布了1.0.0-alpha04版本,新增offscreenPageLimit功能,该功能在ViewPager上并不友好,现在官方将此功能延续下来,这回是骡子是马呢?赶紧拉出来溜溜;

阅读指南:

  • 内容基于ViewPager21.0.0-alpha04版本讲解,由于正式版还未发布,如有功能变动有劳看官指出

  • 内容重点:介绍ViewPager2的offscreenPageLimit特性和预加载机制,另外包括Adapter的状态和Fragment的生命周期等内容

2 ViewPager 顽疾

顽疾是什么鬼,没有这么严重吧。ViewPager有两个毛病:不能关闭预加载和更新Adapter不生效,所以开头我为什么说offscreenPageLimit在ViewPager上十分不友好;

本质上是因为offscreenPageLimit不能设置成0(设置成0就是想象中的关闭预加载);

上面是ViewPager默认情况下的加载示意图,当切换到当前页面时,会默认预加载左右两侧的布局到ViewPager中,尽管两侧的View并不可见的,我们称这种情况叫预加载;由于ViewPager对offscreenPageLimit设置了限制,页面的预加载是不可避免;

ViewPager

private static final int DEFAULT_OFFSCREEN_PAGES = 1;

public void setOffscreenPageLimit(int limit) {
    if (limit //不允许小于1
        Log.w(TAG, "Requested offscreen page limit " + limit + " too small; defaulting to "
                + DEFAULT_OFFSCREEN_PAGES);
        limit = DEFAULT_OFFSCREEN_PAGES;
    }
    if (limit != mOffscreenPageLimit) {
        mOffscreenPageLimit = limit;
        populate();
    }
}

ViewPager强制预加载的逻辑在Fragment配合ViewPager使用时依然存在.

Fragment懒加载前因后果

先说PagerAdapter:

PagerAdapter常用方法如下:

  • instantiateItem(ViewGroup container, int position)初始化ItemView,返回需要添加ItemView

  • destroyItem(iewGroup container, int position, Object object)销毁ItemView,移除指定的ItemView

  • isViewFromObject(View view, Object object)View和Object是否对应

  • setPrimaryItem(ViewGroup container, int position, Object object) 当前页面的主Item

  • getCount()获取Item个数

先说setPrimaryItem(ViewGroup container, int position, Object object),该方法表示当前页面正在显示主要Item,何为主要Item?如果预加载的ItemView已经划入屏幕,当前的PrimaryItem依然不会改变,除非新的ItemView完全划入屏幕,且滑动已经停止才会判断;

由于ViewPager不可避免的进行布局预加载,造成PagerAdapter必须提前调用instantiateItem(ViewGroup container, int position)方法,instantiateItem()是创建ItemView的唯一入口方法,所以PagerAdapter的实现类FragmentPagerAdapter和FragmentStatePagerAdapter必须抓住该方法进行Fragment对象的创建;

碰巧的是,FragmentPagerAdapter和FragmentStatePagerAdapter一股脑的在instantiateItem()中进行创建且进行add或attach操作,并没有在setPrimaryItem()方法中对Fragment进行操作;

因此,预加载会导致不可见的Fragment一股脑的调用onCreate、onCreateView、onResume等方法,用户只能通过Fragment.setUserVisibleHint()方法进行识别;

大多数的懒加载都是对Fragment做手脚,结合生命周期方法和setUserVisibleHint状态,控制数据延迟加载,而布局只能提前进入;

3 ViewPager2 基本使用

build.gradle引入

implementation 'androidx.viewpager2:viewpager2:1.0.0-alpha04'

布局文件添加

<androidx.viewpager2.widget.ViewPager2android:id="@+id/view_pager"android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1" />

设置ViewHolder+Adapter

ViewPager2 viewPager = findViewById(R.id.view_pager2);
viewPager.setAdapter(new RecyclerView.Adapter() { @Overridepub
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值