ViewPager(一):加载机制与优化(1)

文章讲述了作者在使用ViewPager制作日历时遇到的卡顿问题,通过研究发现ViewPager的预加载机制导致性能下降。通过设置合理的可滑动范围并利用SparseArray保存已加载的页面,避免重复加载,从而提高滑动流畅度。
摘要由CSDN通过智能技术生成

以前用viewPager做轮播图,左右滑动感觉挺流程,没感觉有卡顿的现象;但实现现在又用viewPager做日历,日历的模块全部是用canvas画出来的,在这里有一些算法要去处理,viewpager左右滑动好像没那么流畅了。这个时候我就在想如何优化viewpager,尽量让它左右滑动的时候不那么卡顿,至少测试不找自己麻烦。先要研究如何优化,那么就一定要了解viewPager的预加载机制。

正文

首先我们将viewpager的可滑动范围设置为3000,在这里我故意设置成3000

public YueLiAdapter(Context context, TypedArray array, YueLiView monthCalendarView, Class clzz, Resources resources) {

mContext = context;

mArray = array;

mMonthCalendarView = monthCalendarView;

mViews = new SparseArray<>();

mSkinClzz = clzz;

mSkinResources = resources;

mMonthCount = array.getInteger( R.styleable.YueLiView_yueli_count, 3000 );

}

@Override

public int getCount() {

return mMonthCount;

}

@Override

public Object instantiateItem(ViewGroup container, int position) {

Log.i(“getCount”, “###”+position+" " );

}

那么初始化的时候,我们发现日志出现了这么3条信息

image

没错就是这3条信息,最开始的时候打印了1500,我们发现这个数字就是3000的一半,是的,在初始化的时候我们设置了getCount()的数值是3000,那么在执行instantiateItem(ViewGroup container,int position)的时候,这里面的position的值就是1500,viewPager自动会从position=getCount()/2位置加载最开始的页面,然后向前预加载一个页面,再向后预加载一个页面,也就是加载了position=1499的页面和position=1501的页面。

我们移动页面

image

当我们再向左滑动一页的时候,那么这个时候viewPager显示的是position=1501的页面,但是它还会再向后面再预加载一个页面,也就是position=1502的页面。如果一直向后就一直预加载,直到当position=3000的时候就不会预加载了。那么向前预加载也是这样的原理,当我们的页面在position=1501这个页面的时候再向右滑动一页,那么当前显示的就是position=1500的页面,viewPager也会再向前预加载一个页面,也就是position=1499的页面。

那么问题就来了,position=1499的这个页面不是已经加载过了吗,再加载一遍不是又要浪费性能了吗?那么怎么能让加载过的页面不再加载了呢?其实我们可以用sparseArray去保存加载过的页面,如果下次再预加载的时候,已经保存过的页面就不用在加载了,这样就不用再耗费性能了、也就没那么卡顿了。那么为什么用sparseArray而不用hashMap,其实sparseArray性能更好,更加节省内存,这里就不多做解释了。

public class YueLiAdapter extends PagerAdapter {

private SparseArray mViews;//用sparseArray保存加载过的页面

private Context mContext;

private TypedArray mArray;

private YueLiView mMonthCalendarView;

private int mMonthCount;

private Class mSkinClzz;

private Resources mSkinResources;

public YueLiAdapter(Context context, TypedArray array, YueLiView monthCalendarView, Class clzz, Resources resources) {

mContext = context;

mArray = array;

mMonthCalendarView = monthCalendarView;

mViews = new SparseArray<>();

mSkinClzz = clzz;

mSkinResources = resources;

mMonthCount = array.getInteger( R.styleable.YueLiView_yueli_count, 3000 );//初始化范围为3000

}

@Override

public int getCount() {

return mMonthCount;

}

@Override

public Object instantiateItem(ViewGroup container, int position) {

if (mViews.get( position ) == null) {//首先判断mViews中是否保存了之前加载过的页面,如果没有加载过就加载,如果加载过了,那么就不用加载了

int date[] = getYearAndMonth( position );

YueView monthView = new YueView( mContext, mArray, date[0], date[1] );

monthView.setId( position );

monthView.setLayoutParams( new LayoutParams( LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT ) );

monthView.skinRefresh( mSkinClzz, mSkinResources );

monthView.invalidate();

monthView.setOnDateClickListener( mMonthCalendarView );

mViews.put( position, monthView );//将加载的页面view保存在sparseArray里面

}

container.addView( mViews.get( position ) );//从sparseArray里面获取页面view用于显示

return mViews.get( position );//从sparseArray里面获取保存的页面view

}
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

总结

Android架构学习进阶是一条漫长而艰苦的道路,不能靠一时激情,更不是熬几天几夜就能学好的,必须养成平时努力学习的习惯。所以:贵在坚持!

上面分享的字节跳动公司2020年的面试真题解析大全,笔者还把一线互联网企业主流面试技术要点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。

就先写到这,码字不易,写的很片面不好之处敬请指出,如果觉得有参考价值的朋友也可以关注一下我

①「Android面试真题解析大全」PDF完整高清版+②「Android面试知识体系」学习思维导图压缩包阅读下载,最后觉得有帮助、有需要的朋友可以点个赞

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!

外链图片转存中…(img-ll6FBu8h-1712301695540)]

[外链图片转存中…(img-sNyCgJ85-1712301695541)]

[外链图片转存中…(img-HhtmgwZ7-1712301695541)]

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!
  • 29
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值