ViewPager 优化
来源:互联网 发布:淘宝拍图片要多少钱 编辑:程序博客网 时间:2024/04/29 21:02
作者原帖是模仿了QQ音乐的一个功能,我觉得比较有用的是ViewPager的优化。提供了很好的性能优化示例。
转自 http://bxbxbai.gitcafe.io/2015/04/07/swipe-playbar/
可以滑动切歌的播放控制条(模仿QQ音乐)
看了QQ音乐Android版有这个功能,觉得挺好玩的,就模仿它做了一个demo,可以滑动切歌(转换的gif严重失真,只能截图了 -.-)
项目地址:https://github.com/bxbxbai/SwipePlaybarDemo
下载地址:http://vdisk.weibo.com/s/GGofvp4_QVU/1428410542
底部播放条的歌曲信息可以滑动切换,并且专辑图会转动
##看看截图
这个是4个播放条的截图:
##实现
这个功能就是使用ViewPager
这个组件来实现,然后最主要的就是为这个ViewPager
写一个PagerAapter
。这个PagerAdapter
写起来也容易,但是我在这个类里做了一些优化。
这个PagerAdapter
的全部代码就在下面:
/** * PlayBar ViewPager Adapter * * @author bxbxbai*/public class PlayCtrlBarPagerAdapter extends PagerAdapter { private static final int NUM_SONGS = 10; private static final int ANIMATOR_DURATION = 1000 * 10; private LayoutInflater mInflater; private Queue<View> mReusableViews; public PlayCtrlBarPagerAdapter(Context context) { mInflater = LayoutInflater.from(context); mReusableViews = new ArrayDeque<>(NUM_SONGS); } @Override public int getCount() { return NUM_SONGS; } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } @Override public void destroyItem(ViewGroup container, int position, Object object) { if (object instanceof View) { container.removeView((View) object); mReusableViews.add((View) object); } } @Override public Object instantiateItem(ViewGroup container, int position) { View v = mReusableViews.poll(); if (v == null) { v = mInflater.inflate(R.layout.layout_music, container, false); setAnimator(v); } bindData(v, position); container.addView(v); return v; } private void bindData(View v, int position) { TextView songName = ButterKnife.findById(v, R.id.tv_song_name); songName.setText("Try - " + position); ImageView artistImage = ButterKnife.findById(v, R.id.iv_artist_cover); if (position % 2 == 1) { artistImage.setImageResource(R.drawable.adele); } else { artistImage.setImageResource(R.drawable.bxbxbai); } } @Override public float getPageWidth(int position) { return 1.0f; } public static void setAnimator(View view) { ObjectAnimator animator = ObjectAnimator.ofFloat(view.findViewById(R.id.iv_artist_cover), "rotation", 0f, 360f); animator.setRepeatCount(Integer.MAX_VALUE); animator.setDuration(ANIMATOR_DURATION); animator.setInterpolator(new LinearInterpolator()); view.setTag(R.id.tag_animator, animator); }}
##优化PagerAdapter
PagerAdapter
和Android中ListView
的Adapter
类似,但是一个主要的不同就是PagerAdapter
提供了一个回调方法来让我们处理销毁的Item。
一个ViewPager
默认的offScreenPageLimit
为1,也就是说当一个ViewPager
当前显示页为2
,那么PagerAdapter
中还存在左右两个Pager,也就是1
和3
。此时,如果我们将ViewPager
滑向3
,那么PagerAdapter
首先会通过public void destroyItem(ViewGroup container, int position, Object object)
方法销毁第1
个Item,然后通过public Object instantiateItem(ViewGroup container, int position)
生成第4
的Item,并且显示当前的Item(为3
)。此时,PagerAdapter
中存在的Item为2
和4
从这个思路出发,我也就可以在destroyItem
方法中保存这个object,然后在instantiateItem
中使用。
###看上面的代码
我写了一个Queue<View> mReusableViews;
在destroyItem
中保存被销毁的Item,然后在instantiateItem
方法中首先去mReusableViews
中获取。
如果存在可以重用的Item,那么就不用inflate一个View了,直接绑定数据就可以。否则就创建一个新的View来使用
在实验过程中发现,如果ViewPager
的offScreenPageLimit
为1,那么只需要创建3个View,其他的View都可以重复使用,这样就可以提升性能了
##如何让ImageView转起来
在View
绑定数据的时候通过一个工具方法,为每个View
都设置一个ObjectAnimator
属性动画。然后我为这个ViewPager
专门写了一个ViewPager.PageTransformer
类
其实代码也很简单,就是当某一个page完全显示的时候(position为0),开始动画,否则停止动画
如果你需要在ViewPager
上添加一些其他特效,那么可以通过addTransformer
方法添加PageTransformer
/** * 播放条的PagerTransformer * * @author bxbxbai */public class PlaybarPagerTransformer implements ViewPager.PageTransformer { private List<ViewPager.PageTransformer> mTransformers = new ArrayList<>(); @Override public void transformPage(View page, float position) { for (ViewPager.PageTransformer transformer : mTransformers) { transformer.transformPage(page, position); } //处理图片旋转 StopWatch.log("page: " + page + ", pos: " + position); if (position == 0) { ObjectAnimator animator = (ObjectAnimator) page.getTag(R.id.tag_animator); if (animator != null) { animator.start(); } } else if (position == -1 || position == -2 || position == 1) { ObjectAnimator animator = (ObjectAnimator) page.getTag(R.id.tag_animator); if (animator != null) { animator.end(); } } } public void addTransformer(ViewPager.PageTransformer transformer) { if (transformer != null) { mTransformers.add(transformer); } }}
Dependency - 依赖
- Java Development Kit (JDK) 7 +
- com.android.tools.build:gradle:1.0.0
- Android SDK
- Android SDK Build-tools 21.1.2
Build - 构建
git clone https://github.com/bxbxbai/SwipePlaybarDemo.git
用最新的IntelliJ IDE导入工程(Import Project),然后等待IDE下载gradle和依赖包即可
- ViewPager 优化
- 优化ViewPager切换效果
- Fragment传值-ViewPager优化
- fragment+viewpager的优化
- viewpager的优化
- Android ViewPager优化
- 关于fragment+viewpager的优化
- Viewpager优化流畅度/内存
- ViewPager卡顿优化实战
- Viewpager的刷新机制优化
- ViewPager+Framgnet使用的优化
- 208.m1-ViewPager的优化
- ViewPager预加载及其优化
- ViewPager切换动画及性能优化
- ViewPager -- Fragment 切换卡顿 性能优化
- Android viewpager结合fragment的相关优化
- Android优化之ViewPager的懒加载
- ViewPager 快速切换卡顿 --性能优化
- oracle触发器中增删改查本表 -自治事务
- 使用eventqueue.invokelater()好处、原因
- Objective-C 【This is ARC】
- 模型过度拟合
- iOS8新特性IBDesignable
- ViewPager 优化
- HDU5053-the Sum of Cube-2014 ACM/ICPC Asia Regional Shanghai Online(水题求立方和)
- informatica安装ping不通域的解决办法
- android中的各个单位
- 编写第一个程序HelloWorld(你好,世界)
- Oracle行转列和列转行
- KVO实现机制 & 如何自己动手实现 KVO
- 通达OA 小飞鱼工作流在线培训教程(八)常用表单控件
- Opencv 三对角线矩阵(Tridiagonal Matrix)解法之(Thomas Algorithm)