zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    Leetcode总结之Tree
    Leetcode总结之DFS
    Leetcode总结之Backtracking
    策略模式(设计模式_02)
    面向对象思想设计_计算器小程序(设计模式入门篇_01)
    Android GridView 滑动条设置一直显示状态
    dp暑假专题 训练记录
    dp入门 专题记录 2017-7-26
    dp问题 -挑战例题 2017-7-24
    贪心思维 专题记录 2017-7-21
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/4510975.html
Copyright © 2011-2022 走看看