這個東西我在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