这个东西我在eoeAndroid上首发的,但没有详细的实现说明:http://www.eoeandroid.com/thread-317901-1-1.html
在csdn上进行详细的说明吧。(同时上两个社区,这真是个坏毛病,以后专注csdn好了)。
1.用过网易云音乐客户端应该都懂得它那个播放界面,是蛮炫的。先看我实现的效果图吧:
自定义SeekBar这里少了点东西,进度条应该有两种颜色表示进度,一种是当前播放进度,一种是下载进度。我只实现了第一个,第二个要实现的话还需要重载SeekBar。
2. 转盘实现过程:
(1).反编译网易云音乐apk,把它的图拿过来(这里主要是进度条和那个转盘以及把手(neddle意思好像更明确些));
(2).转盘的绘制,需要具备的2D绘图基础知识:
SurfaceView的使用;
canvas.save()和cavas.restore();的使用;
Matrix的使用;
如果您已经能够熟练的使用这些东西,那实现起来完全无障碍;当然如果不熟,也可以看下我的源码,哈哈。
(3)把柄是不动的,把图画上去即可;
中间的十字叉需要自己绘制的,创建一张位图,然后往这张位图上画一个正的十字叉;
假设转盘转一圈需要十秒,SurfaceView的刷新间隔是10ms,那么每绘制一次,旋转的角度增加为360 / (10000 / 10);超过360则重置为0;
把这个增量post给旋转矩阵,然后用这个旋转矩阵绘制出当前帧的位图;
(4)绘图函数:
- private void doDraw(Canvas c) {
- // 去锯齿
- c.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG
- | Paint.FILTER_BITMAP_FLAG));
- int cx = mWidth / 2;
- int cy = mHeight / 2;
- drawBmp(c, discBgBmp, cx, cy, null);
- if(mDiscMatrix == null){
- mDiscMatrix = new Matrix();
- mDiscMatrix.setTranslate(mWidth / 2 - discBmp.getWidth() / 2f,
- mHeight / 2 - discBmp.getHeight() / 2f);
- }
- if(mLcMatrix == null){
- mLcMatrix = new Matrix();
- mLcMatrix.setTranslate(mWidth / 2 - (discBmp.getWidth() - 60) / 2f,
- mHeight / 2 - (discBmp.getHeight() - 60) / 2f);
- }
- if (mIsPlay) {
- if (mRotates >= 360) {
- mRotates = 0;
- mDiscMatrix.reset();
- mLcMatrix.reset();
- mDiscMatrix.setTranslate(mWidth / 2 - discBmp.getWidth() / 2f,
- mHeight / 2 - discBmp.getHeight() / 2f);
- mLcMatrix.setTranslate(mWidth / 2 - (discBmp.getWidth() - 60) / 2f,
- mHeight / 2 - (discBmp.getHeight() - 60) / 2f);
- }
- mDiscMatrix.postRotate(everyRotate, cx, cy);
- mLcMatrix.postRotate(everyRotate, cx, cy);
- mRotates += everyRotate;
- }
- if(mLcBmp == null){
- int w = discBmp.getWidth() - 60;
- int h = discBmp.getHeight() - 60;
- mLcBmp = Bitmap.createBitmap(w, h, Config.ARGB_4444);
- Canvas c2 = new Canvas(mLcBmp);
- Paint p = new Paint();
- c2.drawColor(Color.TRANSPARENT, Mode.CLEAR);
- p.setColor(Color.LTGRAY);
- p.setStyle(Style.FILL);
- c2.drawCircle(w / 2, h / 2, Math.min(w, h) / 2, p);
- p.setColor(Color.DKGRAY);
- p.setStrokeWidth(10f);
- c2.drawLine(0, h / 2, w, h / 2, p);
- c2.drawLine(w / 2, 0, w / 2, h, p);
- }
- c.drawBitmap(mLcBmp, mLcMatrix, null);
- c.drawBitmap(discBmp, mDiscMatrix, null);
- int left = mWidth / 2 - needleBmp.getWidth();
- int top = 30;
- c.drawBitmap(needleBmp, left, top, null);
- }
3. 自定义SeekBar实现
这个东西应该除了入门者之外都已经掌握,这里也再啰嗦下,
来源于Android 源码的中SeekBar的style, 根据它的源码,将seekBar的style更改如下:
SeekBar 的Style:
- <style name="SeekBar" parent="@android:style/Widget">
- <item name="android:indeterminateOnly">false</item>
- <item name="android:progressDrawable">@drawable/bg_seekbar</item>
- <item name="android:indeterminateDrawable">@drawable/bg_seekbar</item>
- <item name="android:minHeight">50dip</item>
- <item name="android:maxHeight">50dip</item>
- <item name="android:thumb">@drawable/bg_play_pause</item>
- <item name="android:thumbOffset">0dip</item>
- <item name="android:focusable">true</item>
- </style>
bg_seekbar的定义也是根据源码改的,为了显示正常,做了一点点裁切:
- <?xml version="1.0" encoding="utf-8"?>
- <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:id="@android:id/background">
- <nine-patch android:src="@drawable/play_ctrl_barbg"/>
- </item>
- <item android:id="@android:id/secondaryProgress">
- <clip>
- <scale android:drawable="@drawable/play_ctrl_readybar" android:scaleWidth="80%" />
- </clip>
- </item>
- <item android:id="@android:id/progress">
- <clip>
- <scale android:drawable="@drawable/play_ctrl_currbar" android:scaleWidth="80%" />
- </clip>
- </item>
其中标示的图像资源在源码中都可以找到。
layout中SeekBar引用这个style即可。
4. 源码下载地址:http://download.csdn.net/detail/lqh810/6721349