可以滑动切歌的播放控制条(模仿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和依赖包即可