Android 開發之網易雲音樂(或QQ音樂)的播放界面轉盤和自定義SeekBar的實現


這個東西我在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)繪圖函數:

  1. private void doDraw(Canvas c) { 
  2.  
  3.         // 去鋸齒 
  4.         c.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG 
  5.                 | Paint.FILTER_BITMAP_FLAG)); 
  6.  
  7.         int cx = mWidth / 2; 
  8.         int cy = mHeight / 2; 
  9.         drawBmp(c, discBgBmp, cx, cy, null); 
  10.  
  11.         if(mDiscMatrix == null){ 
  12.             mDiscMatrix = new Matrix(); 
  13.             mDiscMatrix.setTranslate(mWidth / 2 - discBmp.getWidth() / 2f, 
  14.                     mHeight / 2 - discBmp.getHeight() / 2f); 
  15.         } 
  16.          
  17.         if(mLcMatrix == null){ 
  18.             mLcMatrix = new Matrix(); 
  19.             mLcMatrix.setTranslate(mWidth / 2 - (discBmp.getWidth() - 60) / 2f, 
  20.                     mHeight / 2 - (discBmp.getHeight() - 60) / 2f); 
  21.         } 
  22.          
  23.         if (mIsPlay) { 
  24.             if (mRotates >= 360) { 
  25.                 mRotates = 0; 
  26.                 mDiscMatrix.reset(); 
  27.                 mLcMatrix.reset(); 
  28.                 mDiscMatrix.setTranslate(mWidth / 2 - discBmp.getWidth() / 2f, 
  29.                         mHeight / 2 - discBmp.getHeight() / 2f); 
  30.                 mLcMatrix.setTranslate(mWidth / 2 - (discBmp.getWidth() - 60) / 2f, 
  31.                         mHeight / 2 - (discBmp.getHeight() - 60) / 2f); 
  32.             } 
  33.             mDiscMatrix.postRotate(everyRotate, cx, cy); 
  34.             mLcMatrix.postRotate(everyRotate, cx, cy); 
  35.             mRotates += everyRotate; 
  36.         } 
  37.          
  38.         if(mLcBmp == null){ 
  39.             int w = discBmp.getWidth() - 60; 
  40.             int h = discBmp.getHeight() - 60; 
  41.             mLcBmp = Bitmap.createBitmap(w, h, Config.ARGB_4444); 
  42.             Canvas c2 = new Canvas(mLcBmp); 
  43.             Paint p = new Paint(); 
  44.              
  45.             c2.drawColor(Color.TRANSPARENT, Mode.CLEAR); 
  46.              
  47.             p.setColor(Color.LTGRAY); 
  48.             p.setStyle(Style.FILL); 
  49.             c2.drawCircle(w / 2, h / 2, Math.min(w, h) / 2, p); 
  50.              
  51.             p.setColor(Color.DKGRAY); 
  52.             p.setStrokeWidth(10f); 
  53.             c2.drawLine(0, h / 2, w, h / 2, p); 
  54.             c2.drawLine(w / 2, 0, w / 2, h, p); 
  55.              
  56.         } 
  57.          
  58.         c.drawBitmap(mLcBmp, mLcMatrix, null); 
  59.         c.drawBitmap(discBmp, mDiscMatrix, null); 
  60.          
  61.         int left = mWidth / 2 - needleBmp.getWidth(); 
  62.         int top = 30; 
  63.         c.drawBitmap(needleBmp, left, top, null); 
  64.          
  65.     } 
 
        

 

 

3. 自定義SeekBar實現

這個東西應該除了入門者之外都已經掌握,這里也再啰嗦下,

來源於Android 源碼的中SeekBar的style, 根據它的源碼,將seekBar的style更改如下:

 

SeekBar 的Style:

  1. <style name="SeekBar" parent="@android:style/Widget"
  2.        <item name="android:indeterminateOnly">false</item
  3.        <item name="android:progressDrawable">@drawable/bg_seekbar</item
  4.        <item name="android:indeterminateDrawable">@drawable/bg_seekbar</item
  5.        <item name="android:minHeight">50dip</item
  6.        <item name="android:maxHeight">50dip</item
  7.        <item name="android:thumb">@drawable/bg_play_pause</item
  8.        <item name="android:thumbOffset">0dip</item
  9.        <item name="android:focusable">true</item
  10.    </style

 

 

bg_seekbar的定義也是根據源碼改的,為了顯示正常,做了一點點裁切:

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <layer-list xmlns:android="http://schemas.android.com/apk/res/android"
  3.      
  4.     <item android:id="@android:id/background"
  5.         <nine-patch android:src="@drawable/play_ctrl_barbg"/> 
  6.     </item
  7.      
  8.     <item android:id="@android:id/secondaryProgress"
  9.         <clip
  10.         <scale android:drawable="@drawable/play_ctrl_readybar" android:scaleWidth="80%" /> 
  11.         </clip
  12.     </item
  13.     <item android:id="@android:id/progress"
  14.          <clip
  15.         <scale android:drawable="@drawable/play_ctrl_currbar" android:scaleWidth="80%" /> 
  16.         </clip
  17.     </item

其中標示的圖像資源在源碼中都可以找到。

 

layout中SeekBar引用這個style即可。

 

4. 源碼下載地址:http://download.csdn.net/detail/lqh810/6721349


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM