本篇文章介绍自定义View配合属性动画来实现如下的效果

实现思路如下:

根据播放按钮的图片大小计算出圆形进度条的大小

根据音频的时间长度计算出圆形进度条绘制的弧度

通过Handler刷新界面来更新圆形进度条的进度

具体实现过程分析:

首先来看看自定义View中定义的一些成员变量

//表示坐标系中的一块矩形区域

private RectF mRectF;

//画笔

private Paint mPaint;

//画笔宽度

private int mCircleStoreWidth = 3;

//最大进度值

private int mMaxProcessValue = 100;

//进度值

private int mProcessValue;

private int width;

private int height;

//播放器按钮id值

private int bitmapPlay;

private int bitmapStop;

//播放器按钮Bitmap对象

private Bitmap drawBitmapPlay;

private Bitmap drawBitmapStop;

private Context context;

//标记是否正在播放中

private boolean isPlay;

初始化自定义View,在这里获取播放器按钮图片以及初始化画布画笔对象以及设置将画笔设置抗锯齿

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来获取播放器按钮图片

在attrs.xml中新建如下:

然后在xml布局的自定义View中加入就能获取图片的id值了

circle:play_image="@mipmap/play_button"

circle:stop_image="@mipmap/stop_button"

然后我们重写onMeasure()来测量圆形进度条绘制的位置

@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;

}

获取播放器按钮图片的大小后,计算出进度条的相应的坐标放入RectF对象中,RectF对象是用来表示坐标系中的一块矩形区域,用于在特定的位置画图

然后我们就可以通过重写onDraw()方法来绘制View了

@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);

}

}

要点其实就是canvas.drawArc()方法在RecfF的位置里画弧形,通过音频播放的开始时间/总时间*360来计算出弧度

要注意的是每次调用onDraw()方法的时候都需要先将canvas画透明色来起到清屏的作用

通过handler来每150毫秒刷新一次界面

private Handler handler = new Handler() {

public void handleMessage(Message msg) {

switch (msg.what) {

case 1:

//定时更新界面

if (isPlay) {

mProcessValue += 150;

if (mProcessValue == mMaxProcessValue) {

isPlay = false;

}

invalidate();

Message message = handler.obtainMessage(1);

handler.sendMessageDelayed(message, 150);

}

}

super.handleMessage(msg);

}

};

最后是一些包装方法,很简单不仔细介绍了

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();

}

音频播放的逻辑实现部分因为不属于自定义view因此可以自行参考demo

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

android 自定义音乐圆形进度条,Android自定义View实现音频播放圆形进度条相关推荐

  1. mc服务器音乐文件夹在哪,我的世界 自定义音乐添加方法 MC怎么自定义音乐

    我的世界自定义音乐添加图文攻略 我的世界怎么自添加定义音乐 我的世界游戏中相信很多玩家都不知道应该怎样添加自定义音乐吧,今天小编就来给大家讲解一下游戏中添加自定义音乐的方法,希望可以帮到大家. 我的世 ...

  2. android 扫描音乐,native.js扫描android手机本地音乐

    解决了. mui.init(); document.addEventListener("plusready", function() { if(plus.os.name == &q ...

  3. php怎样查看视频播放的进度条,H5中视频与音频标签和进度条如何使用

    这次给大家带来H5中视频与音频标签和进度条如何使用,H5中视频与音频标签和进度条使用的注意事项有哪些,下面就是实战案例,一起来看一下. 最近项目中使用Html5的video和audio标签来在线播放视 ...

  4. css环形进度条clip,使用CSS clip 属性实现音频播放圆环进度条

    这是效果 突然有需求要做一个圆环的音频播放进度条(上图效果),自己琢磨尝试了半天,也没有实现.最后度娘一下,才知道css还有一个clip属性,完美实现需求.分享一下,说不定能帮其它小伙伴.至于有没有用 ...

  5. android实现喇叭播放效果图,自定义View 实现音频播放效果

    这已经是第二次实现这种效果了.记录下来. 首先看下效果图.这里就不搞gif 了 image.png 1.首先确定需要音频条得数量 2.根据大小计算出 间距和音频条得宽度 3.绘制初始样式 4.利用ha ...

  6. Android自定义滑动进度条,Android自定义View实现圆形水波进度条

    每次听到某大牛谈论自定义View,顿时敬佩之心,如滔滔江水连绵不绝,心想我什么时候能有如此境界,好了,心动不如行动,于是我开始了自定义View之路,虽然过程有坎坷,但是结果我还是挺满意的.我知道大牛还 ...

  7. 精通Android自定义View(十二)绘制圆形进度条

    1 绘图基础简析 1 精通Android自定义View(一)View的绘制流程简述 2 精通Android自定义View(二)View绘制三部曲 3 精通Android自定义View(三)View绘制 ...

  8. android 环形时间显示_Android_Android实现自定义圆形进度条,今天无意中发现一个圆形进度 - phpStudy...

    Android实现自定义圆形进度条 今天无意中发现一个圆形进度,想想自己实现一个,如下图: 基本思路是这样的: 1.首先绘制一个实心圆 2.绘制一个白色实心的正方形,遮住实心圆 3.在圆的中心动态绘制 ...

  9. android 音乐播放 圆形进度条

    上次 上传gif后 没动 不知道这次会不会动 在依次吐槽 csdn的博客模板   原来要选择 无水印 我的天 gif才成功 上次写了一个音乐播放器 今天吧里面的一个效果写出来 写博客的习惯要慢慢养成 ...

最新文章

  1. sql中小数位四舍五入控制
  2. 云炬Android开发笔记 3-1项目架构初始化
  3. eclipse Plugin execution not covered by lifecycle configuration:maven.***.plugin
  4. 从零搭建nginx服务器
  5. java 中张孝祥老师_谁有传智博客张孝祥老师的Java视频——必须是完整的
  6. e7用什么主板_主板当中的纽扣电池有什么用?电池没电了会怎样?
  7. android java 图像显示不出来_Java-Android Studio无法在图像视图中显示图像
  8. python学习笔记15-执行环境
  9. C# 自定义网格 dataGridView 禁止编辑 + 禁止自动生成新列 + 禁止生成新行 + 禁止删除行 + 禁止多选 + 禁止行选中 + 禁止改变列宽度 行高度
  10. redis的简单操作
  11. Android Studio百度地图开发:如何注册和获取百度地图开发密钥?
  12. 网易云音乐encseckey算法php,求助网易云音乐_secretKey及_encSecKey获取
  13. 程序员加油站 -- 不是人人都懂的学习要点
  14. c/c++游戏编程之Easyx图形库基础
  15. 云桌面场景化升级新作,锐捷网络发布全新远程办公“U空间”
  16. 阿里云天池大数据长期赛:金融风控-贷款违约预测(含代码)
  17. 2015合肥市第 32 届青少年信息学(计算机)奥林匹克竞赛小学组试题
  18. 基于Python爬虫的大众点评商家评论的文本挖掘
  19. 明日天津,择日来京--我回来了(九月二十日更新)
  20. 各大手机厂商快应用入口

热门文章

  1. M_Map画南海水深地形图
  2. Pandas缺失数据
  3. 华为笔试题---明明的随机数
  4. UITextField 限制用户输入小数点后位数的方法
  5. lua创建文件和文件夹
  6. 转:45 Useful JavaScript Tips, Tricks and Best Practices
  7. 最近想做个音乐共享的软件
  8. VSS的每日自动备份
  9. 文本的DES加密 MD5散列值 DSA的数字签名
  10. 结构体中定义函数指针