另一种方法:当使用ViewPager加载大量View时卡顿严重的简单解决方法
来源:互联网 发布:mac系统怎么安装ae插件 编辑:程序博客网 时间:2024/04/30 14:27
在做项目的时候,需要自定义一个日历的控件,一开始采用普遍的做法:ViewPager+GridView。很容易想到,在使用的时候非常卡,加载非常慢。查了相关资料,发现基本上都是这种方法:ViewPager嵌套GridView引发的一系列UI卡顿不顺畅的问题,但都未曾从根本上解决问题。后来想到使用异步加载数据的方法,在初始化控件的时候,异步加载需要的日历数据,然后post更新界面,这种方法虽然加快了加载速度,但是滑动还是非常卡,严重影响体验。这时,作者查看了源代码,每次ViewPager在滑动的时候会每次new它的Adapter里面的page并加载数据,这样的方式效率极其低下,基本上没有重用。
既然是Page,一次只显示一页,每页的View都一样,那么何必每次在加载的时候再去new一页page,直接使用已经加载过的Page,只改变Page里面的数据就行了。
基于这种想法,在设计的时候就想着控件继承自AdapterView,通过适配器来适应数据;控件需要3个Page,首次加载3页数据,在Page滑动的时候,判断当前Page是否达到边界,然后交换Page,如图一,达到Page重用的目的。
当向右滑动时,当前Page(Page2)将变得不可见,当Page2完全不可见时,Page1变为当前Page(Page2),Page2变成Page3,而Page2变成page1,以此类推。
代码非常简单,下面贴出一部分关键代码:
<pre class="java" name="code"> // set up adapter viewprivate View setupPage(int position, View convert) {View view = mAdapter.getView(position, convert, this);LayoutParams params = view.getLayoutParams();if (null == params)params = new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT);// attachif (view == convert) { // reusedif (-1 != indexOfChild(convert))detachViewFromParent(convert);attachViewToParent(view, -1, params);} elseaddViewInLayout(view, -1, params, true);if (null != mItemClickListener) {view.setOnClickListener(mPageClickListener);}return view;}
然后是配置交换:
private void swapPage(boolean leftToRight) {if (leftToRight) {/** * if should swap the first buffered-page to the last buffered-page */mPosition++;View temp = mBufferedPages[0];mBufferedPages[0] = mBufferedPages[1];mBufferedPages[1] = mBufferedPages[2];mBufferedPages[2] = temp;if (mPageCount - 1 != mPosition)mBufferedPages[2] = setupPage(mPosition + 1, temp);if (mIsJumpToCurrent) { // if is jumped to current positionmIsJumpToCurrent = false;mBufferedPages[0] = setupPage(mPosition - 1, mBufferedPages[0]);}} else {mPosition--;View temp = mBufferedPages[2];mBufferedPages[2] = mBufferedPages[1];mBufferedPages[1] = mBufferedPages[0];mBufferedPages[0] = temp;if (0 != mPosition)mBufferedPages[0] = setupPage(mPosition - 1, temp);if (mIsJumpToCurrent) {mIsJumpToCurrent = false;mBufferedPages[2] = setupPage(mPosition + 1, mBufferedPages[2]);}}requestLayout();if (null != mPageSelectedListener)mPageSelectedListener.onPageSelected(mBufferedPages[1], mPosition);}
但是有一个问题,在使用过程中,如果界面上有动画,滑动会出现问题,楼主还在解决中。
0 1
- 另一种方法:当使用ViewPager加载大量View时卡顿严重的简单解决方法
- ViewPager加载不出View的解决方法
- ViewPager加载大量图片
- 最简单是使用viewpager的方法
- ViewPager组合其他View的简单使用(一)
- ViewPager组合其他View的简单使用(二)
- Viewpager加载大量图片的时候卡顿
- 安卓Viewpager加载大量图片的时候卡顿
- ViewPager的简单使用
- viewpager的简单使用
- viewpager的简单使用
- ViewPager的简单使用
- ViewPager的简单使用
- viewpager的简单使用
- viewPager的简单使用
- ViewPager的简单使用
- ViewPager的简单使用
- Viewpager的简单使用
- Linux I2C驱动分析与实现(一)
- Mysql多表left join查询
- 线程间通信之消费生产者模式二notify()
- Linux I2C驱动分析与实现(二)
- LINQ TO SQL
- 另一种方法:当使用ViewPager加载大量View时卡顿严重的简单解决方法
- 钩子函数和回调函数
- 【C#基础】【语法04】课堂作业题 01-08
- 二进制、八进制、十进制、十六进制之间转换
- 关于Winform三种Timer的总结
- 原版线程通信之生产消费者模式
- 如何加入linux内核开发社区进行内核开发
- eclipse 报错Conversion to Dalvik format failed: Unable to execute dex: Multiple dex files define Lcom
- git 文件添加、变更的提交