另一种方法:当使用ViewPager加载大量View时卡顿严重的简单解决方法
2014-08-26 18:16
751 查看
在做项目的时候,需要自定义一个日历的控件,一开始采用普遍的做法: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,以此类推。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201408/db2f434487f0105d94de56772544e167)
代码非常简单,下面贴出一部分关键代码:
然后是配置交换:
但是有一个问题,在使用过程中,如果界面上有动画,滑动会出现问题,楼主还在解决中。
既然是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 view private 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); // attach if (view == convert) { // reused if (-1 != indexOfChild(convert)) detachViewFromParent(convert); attachViewToParent(view, -1, params); } else addViewInLayout(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 position mIsJumpToCurrent = 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); }
但是有一个问题,在使用过程中,如果界面上有动画,滑动会出现问题,楼主还在解决中。
相关文章推荐
- 最简单是使用viewpager的方法
- android 解决ViewPager加载大量图片内存溢出问题
- android scrollView中使用viewpager 不显示的解决方法
- 加载大量的xml数据 使用压缩方法解决(当然较小时也可以压缩)
- 使用观察者模式解决ViewPager加载照片中更新其他Fragment内容
- Android 使用ViewPager创建导航页(最简单方法,不服来辩)
- rollviewpager 轮播图开源框架简单使用方法
- Android开发ViewPager的预加载和Fragment的销毁问题,以及tabLayout+ViewPager的使用,tablayout平板适配问题解决
- ViewPager + Fragment的预加载解决方法
- 完美解决Android里面scrollview嵌套及listview嵌套viewpager的滑动冲突问题的简单方法
- 加载大量的xml数据 使用压缩方法解决(当然较小时也可以压缩)
- Viewpager加载大量图片的时候卡顿
- fragment加载webView与ViewPager所带来的滑动冲突问题解决方法
- 简单的解决引导页Viewpager卡顿问题
- Android ViewPager使用详解,加载几个简单布局案例+代码
- android中通过添加view使用ViewPager出现的问题及解决方法
- android 解决ViewPager加载大量图片内存溢出问题
- ListView卡顿优化过程,并解决与viewpager图片加载冲突的问题
- 安卓Viewpager加载大量图片的时候卡顿