激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語(yǔ)言|JavaScript|易語(yǔ)言|vb.net|

服務(wù)器之家 - 編程語(yǔ)言 - Android - Android自定義View實(shí)現(xiàn)音頻播放圓形進(jìn)度條

Android自定義View實(shí)現(xiàn)音頻播放圓形進(jìn)度條

2022-03-07 14:47魯提轄_Ga Android

這篇文章主要為大家詳細(xì)介紹了Android自定義View實(shí)現(xiàn)音頻播放圓形進(jìn)度條,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本篇文章介紹自定義View配合屬性動(dòng)畫來(lái)實(shí)現(xiàn)如下的效果

Android自定義View實(shí)現(xiàn)音頻播放圓形進(jìn)度條

實(shí)現(xiàn)思路如下:

  • 根據(jù)播放按鈕的圖片大小計(jì)算出圓形進(jìn)度條的大小
  • 根據(jù)音頻的時(shí)間長(zhǎng)度計(jì)算出圓形進(jìn)度條繪制的弧度
  • 通過(guò)Handler刷新界面來(lái)更新圓形進(jìn)度條的進(jìn)度

具體實(shí)現(xiàn)過(guò)程分析:

首先來(lái)看看自定義View中定義的一些成員變量

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//表示坐標(biāo)系中的一塊矩形區(qū)域
 private RectF mRectF;
 
 //畫筆
 private Paint mPaint;
 
 //畫筆寬度
 private int mCircleStoreWidth = 3;
 
 //最大進(jìn)度值
 private int mMaxProcessValue = 100;
 
 //進(jìn)度值
 private int mProcessValue;
 
 private int width;
 
 private int height;
 
 //播放器按鈕id值
 private int bitmapPlay;
 private int bitmapStop;
 
 //播放器按鈕Bitmap對(duì)象
 private Bitmap drawBitmapPlay;
 private Bitmap drawBitmapStop;
 
 private Context context;
 //標(biāo)記是否正在播放中
 private boolean isPlay;

初始化自定義View,在這里獲取播放器按鈕圖片以及初始化畫布畫筆對(duì)象以及設(shè)置將畫筆設(shè)置抗鋸齒

?
1
2
3
4
5
6
7
8
9
10
11
12
private void init(Context context, AttributeSet attrs, int defStyleAttr) {
    this.context = context;
    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.circle_progress_image_attrs);
    bitmapPlay = a.getResourceId(R.styleable.circle_progress_image_attrs_play_image, R.mipmap.play_button);
    bitmapStop = a.getResourceId(R.styleable.circle_progress_image_attrs_stop_image, R.mipmap.stop_button);
    a.recycle();
    drawBitmapPlay = BitmapFactory.decodeResource(context.getResources(), bitmapPlay);
    drawBitmapStop = BitmapFactory.decodeResource(context.getResources(), bitmapStop);
    mRectF = new RectF();
    mPaint = new Paint();
    mPaint.setAntiAlias(true);
  }

這里使用了自定義attrs來(lái)獲取播放器按鈕圖片

在attrs.xml中新建如下:

?
1
2
3
4
<declare-styleable name="circle_progress_image_attrs">
    <attr name="play_image" format="reference"/>
    <attr name="stop_image" format="reference"/>
  </declare-styleable>

然后在xml布局的自定義View中加入就能獲取圖片的id值了

?
1
2
circle:play_image="@mipmap/play_button"
circle:stop_image="@mipmap/stop_button"

然后我們重寫onMeasure()來(lái)測(cè)量圓形進(jìn)度條繪制的位置

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    width = measureWidth(widthMeasureSpec);
    height = measureWidth(heightMeasureSpec);
    mRectF.left = width / 2 - drawBitmapPlay.getWidth() / 2;
    mRectF.top = height / 2 - drawBitmapPlay.getHeight() / 2;
    mRectF.right = width / 2 + drawBitmapPlay.getWidth() / 2;
    mRectF.bottom = height / 2 + drawBitmapPlay.getHeight() / 2;
  }
  public int measureWidth(int measureSpec) {
    int result = 0;
    int specMode = MeasureSpec.getMode(measureSpec);
    int specSize = MeasureSpec.getSize(measureSpec);
    if (specMode == MeasureSpec.EXACTLY) {
      result = specSize;
    } else {
      result = 200;
      if (specMode == MeasureSpec.AT_MOST) {
        result = Math.min(specSize, result);
      }
    }
    return result;
  }

獲取播放器按鈕圖片的大小后,計(jì)算出進(jìn)度條的相應(yīng)的坐標(biāo)放入RectF對(duì)象中,RectF對(duì)象是用來(lái)表示坐標(biāo)系中的一塊矩形區(qū)域,用于在特定的位置畫圖

然后我們就可以通過(guò)重寫onDraw()方法來(lái)繪制View了

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Override
  protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawColor(Color.TRANSPARENT);
    //畫圓
    mPaint.setColor(ContextCompat.getColor(context, R.color.orange));
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeWidth(mCircleStoreWidth);
    //    canvas.drawArc(mRectF, -90, 360, false, mPaint);
    mPaint.setColor(ContextCompat.getColor(context, R.color.gray));
    canvas.drawArc(mRectF, -90, ((float) mProcessValue / mMaxProcessValue) * 360, false, mPaint);
    Log.d(TAG, ((float) mProcessValue / mMaxProcessValue) * 360 + "");
    float imageLeft = width / 2 - drawBitmapPlay.getWidth() / 2;
    float imageTop = height / 2 - drawBitmapPlay.getHeight() / 2;
    if (isPlay) {
      canvas.drawBitmap(drawBitmapStop, imageLeft, imageTop, mPaint);
    } else {
      canvas.drawBitmap(drawBitmapPlay, imageLeft, imageTop, mPaint);
    }
  }

要點(diǎn)其實(shí)就是canvas.drawArc()方法在RecfF的位置里畫弧形,通過(guò)音頻播放的開始時(shí)間/總時(shí)間*360來(lái)計(jì)算出弧度
要注意的是每次調(diào)用onDraw()方法的時(shí)候都需要先將canvas畫透明色來(lái)起到清屏的作用

通過(guò)handler來(lái)每150毫秒刷新一次界面

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
private Handler handler = new Handler() {
    public void handleMessage(Message msg) {
      switch (msg.what) {
        case 1:
          //定時(shí)更新界面
          if (isPlay) {
            mProcessValue += 150;
            if (mProcessValue == mMaxProcessValue) {
              isPlay = false;
            }
            invalidate();
            Message message = handler.obtainMessage(1);
            handler.sendMessageDelayed(message, 150);
          }
      }
      super.handleMessage(msg);
    }
  };

最后是一些包裝方法,很簡(jiǎn)單不仔細(xì)介紹了

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public void play() {
    isPlay = true;
    Message message = handler.obtainMessage(1);
    handler.sendMessageDelayed(message, 150);
  }
 
  public void setDuration(int duration) {
    this.mMaxProcessValue = duration;
  }
 
  public void clearDuration() {
    this.mMaxProcessValue = 0;
    this.mProcessValue = 0;
  }
 
  public void pause() {
    isPlay = false;
    invalidate();
  }
 
  public void stop() {
    isPlay = false;
    this.mMaxProcessValue = 0;
    this.mProcessValue = 0;
    invalidate();
  }

音頻播放的邏輯實(shí)現(xiàn)部分因?yàn)椴粚儆谧远xview因此可以自行參考demo

代碼示例: CustomViewSamples

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。

原文鏈接:https://blog.csdn.net/lj402159806/article/details/55803967

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 久久草在线视频 | 激情综合网俺也去 | 中文字幕在线亚洲精品 | 黄网站在线免费 | 黄色av片三级三级三级免费看 | 精品亚洲在线 | 欧美一级全黄 | 久久精品成人影院 | 午夜国内精品a一区二区桃色 | 日本在线不卡免费 | 久久久精品视频网站 | 国产精品视频中文字幕 | 成人免费一区二区三区在线观看 | 亚洲最新无码中文字幕久久 | 日本精品一区二区 | 狠狠操夜夜爱 | 欧美成人精品一级 | 国产毛片视频 | 亚洲91网 | 牛牛热这里只有精品 | 精品亚洲视频在线观看 | 精品国产一区二区三区四区在线 | 亚洲性生活免费视频 | 日本精品视频一区二区三区四区 | 免费啪视频在线观看 | 粉嫩粉嫩一区二区三区在线播放 | 鲁丝一区二区二区四区 | 久久99精品久久久久久秒播蜜臀 | 中文字幕在线观看视频www | 999精品久久久 | 亚洲国产精品久久久久婷婷老年 | 精品国产乱码久久久久久久 | 欧美国产一级片 | 在线播放免费视频 | 国内精品久久久久久久星辰影视 | 亚洲欧洲日产v特级毛片 | 亚洲aⅴ在线观看 | 午夜视频在线免费播放 | 本站只有精品 | 成人一级在线 | 精国品产一区二区三区有限公司 |