ViewPager 优化
2015-09-03 15:15
330 查看
作者原帖是模仿了QQ音乐的一个功能,我觉得比较有用的是ViewPager的优化。提供了很好的性能优化示例。
转自 http://bxbxbai.gitcafe.io/2015/04/07/swipe-playbar/
发表于 Apr 7 2015 | 暂无评论
看了QQ音乐Android版有这个功能,觉得挺好玩的,就模仿它做了一个demo,可以滑动切歌(转换的gif严重失真,只能截图了 -.-)
项目地址:https://github.com/bxbxbai/SwipePlaybarDemo
下载地址:http://vdisk.weibo.com/s/GGofvp4_QVU/1428410542
底部播放条的歌曲信息可以滑动切换,并且专辑图会转动
##看看截图
这个是4个播放条的截图:
##实现
这个功能就是使用
这个
##优化PagerAdapter
一个
从这个思路出发,我也就可以在
###看上面的代码
我写了一个
如果存在可以重用的Item,那么就不用inflate一个View了,直接绑定数据就可以。否则就创建一个新的View来使用
在实验过程中发现,如果
##如何让ImageView转起来
在
其实代码也很简单,就是当某一个page完全显示的时候(position为0),开始动画,否则停止动画
如果你需要在
Java Development Kit (JDK) 7 +
com.android.tools.build:gradle:1.0.0
Android SDK
Android SDK Build-tools 21.1.2
用最新的IntelliJ IDE导入工程(Import Project),然后等待IDE下载gradle和依赖包即可
转自 http://bxbxbai.gitcafe.io/2015/04/07/swipe-playbar/
可以滑动切歌的播放控制条(模仿QQ音乐)
发表于 Apr 7 2015 | 暂无评论看了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和依赖包即可
相关文章推荐
- 杭电OJ-2054_A == B ?
- informatica安装ping不通域的解决办法
- iOS8新特性IBDesignable
- 模型过度拟合
- [LeetCode] Reverse Linked List
- oracle触发器中增删改查本表 -自治事务
- 使用eventqueue.invokelater()好处、原因
- Hibernate的使用
- struts2(二)---ModelDriven模型驱动
- javascript模板方法模式
- struts2(二)---ModelDriven模型驱动
- hdu 1052 Tian Ji -- The Horse Racing(经典贪心)
- opencv学习笔记(三)-读取视频与摄像头
- kettle创建数据库资源库,执行SQL语句有两条执行失败
- java的在线调试工具
- 解决IE支持placeholder的方法
- AIDL自定义实现
- 在Unix中使用Informatica连接SQL+Server
- [LeetCode206] Course Schedule II
- MySQL的MyISAM与InnoDB的索引方式