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

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。