Android 音频进度播放View(原View升级版)
描述:这是一个 声纹进度播放效果的Demo。
项目代码在最后面!!!!跳转到最后
控件效果如下:
此控件是基于之前的控件View加入了音频控制内容和跟随播放音乐进度显示进度
原仅控件文章可点击查看
实现功能:
- 声纹可随机显示也可固定
- 可自定义加载前后两种颜色
- 可选择传入音乐进行播放,音乐播放进度和
- 点击控件可控制音乐暂停和播放
设计核心:
主要的设计核心是依赖于drawRoundRect方法进行声纹条形的绘制,通过MediaPlay添加音乐播放和进度监听。
核心代码:
VoiceProgressView.java 一个声纹进度播放的自定义View 可直接载入layout
package com.ui.design.view.voicePorgress.view;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.media.MediaPlayer;
import android.media.TimedText;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import java.io.IOException;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
/**
* 声纹显示View
* tangxianfeng
* 2021.12.19
*/
public class VoiceProgressView extends View {
private int max = 0; //最大刻度
private int mRectHeight = 0; //高度
private int mRectWeight = 0; //宽度
private Paint mAfterPaint;
private Paint mBeforePaint;
private int mBeforeProgress;//百分比
private List<Integer> intArray = new ArrayList<>();//内置声纹长度
private MediaPlayer mediaPlayer;
private Timer timer;
public VoiceProgressView(Context context) {
this(context, null);
}
public VoiceProgressView(Context context, AttributeSet attrs) {
this(context, attrs, -1);
}
public VoiceProgressView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
if (mAfterPaint == null) {
mAfterPaint = new Paint();
mAfterPaint.setColor(Color.parseColor("#356BD8"));
mAfterPaint.setAntiAlias(true);
}
if (mBeforePaint == null) {
mBeforePaint = new Paint();
mBeforePaint.setColor(Color.parseColor("#ABC8F2"));
mBeforePaint.setAntiAlias(true);
}
}
@Override
protected void onDraw(Canvas canvas) {
if (mRectHeight == 0) {
mRectHeight = getHeight();
}
if (mRectWeight == 0) {
mRectWeight = getWidth();
}
if (max == 0) {
max = mRectWeight / 16;
}
onDrawVoice(canvas); //画声纹
super.onDraw(canvas);
}
/**
* 画刻度
*/
private void onDrawVoice(Canvas canvas) {
if (intArray == null || intArray.size() == 0) {
SecureRandom secureRandom = new SecureRandom();
for (int i = 0; i < max + 1; i++) {
int height = secureRandom.nextInt(40) + 15;
intArray.add(height);
}
}//比实际声纹条数多一
if (canvas == null) return;
for (int i = 1; i < max; i++) {
float height = intArray.get(i % intArray.size());
//刻度间距
int mScaleMargin = 16;
canvas.drawRoundRect(i * mScaleMargin, (mRectHeight + height) / 2, i * mScaleMargin + 8, (mRectHeight - height) / 2, 5, 5, i < mBeforeProgress ? mAfterPaint : mBeforePaint);//播放前后的颜色替换
}
}
//设置默认声纹 可传数组{20,25,38,19,40,25,30,38}
public void setIntArray(List<Integer> intArray) {
this.intArray = intArray;
}
//设置百分百
public void setProgress(float progress) {
Log.e("TEST",progress+"");
if (progress > 100) {
progress = 100;
} else if (progress < 0) {
progress = 0;
}
mBeforeProgress = (int) (max * progress / 100);
postInvalidate();
}
//自定义声纹颜色 传入类型#356BD8
public void initPaintColor(String beforecolor, String aftercolor) {
if (!beforecolor.contains("#") || !aftercolor.contains("#")) {
return;
}//颜色格式需要含#号 简单判断处理下 不然会出错
if (mAfterPaint != null) {
mAfterPaint.setColor(Color.parseColor(beforecolor));
}
if (mBeforePaint != null) {
mBeforePaint.setColor(Color.parseColor(aftercolor));
}
}
//配置音乐
public MediaPlayer configmusic() {
mediaPlayer = new MediaPlayer();
return mediaPlayer;
}
//初识化音乐
public boolean initMusic(){
if (mediaPlayer == null) {
Log.e("VoiceView","mediaPlayer == null");
return false;
}
try {
mediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
Log.e("VoiceView",e.getMessage());
return false;
}
if (timer==null){
timer=new Timer();
TimerTask timerTask= new TimerTask() {
@Override
public void run() {
if (mediaPlayer != null) {
if (mediaPlayer.getCurrentPosition()==mediaPlayer.getDuration()){
setProgress(100);
}else {
// 将位置设置到当前播放位置
setProgress((float) mediaPlayer.getCurrentPosition() * 100 / mediaPlayer.getDuration());
}
}
}
};
timer.schedule(timerTask,500,500);
setOnClickListener(v -> {
if (mediaPlayer.isPlaying()){
pause();
}else {
play();
}
});
}
return true;
}
//播放
public void play() {
mediaPlayer.start();
}
//暂停播放
public void pause() {
mediaPlayer.pause();
}
//重置时间
public void reset(){
mediaPlayer.seekTo(0);
mediaPlayer.pause();
setProgress(0);
}
//销毁
public void destory(){
timer.cancel();
mediaPlayer.release();
mediaPlayer=null;
}
}
使用示例:
VioceProgressActivity.java
import android.content.res.AssetFileDescriptor;
import android.widget.Button;
import android.widget.Toast;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.ui.design.R;
import com.ui.design.main.base.BaseActivity;
import com.ui.design.main.constants.Constants;
import com.ui.design.view.voicePorgress.view.VoiceProgressView;
import java.io.IOException;
@Route(path = Constants.VioceProgressActivity)
public class VioceProgressActivity extends BaseActivity {
private VoiceProgressView voiceProgressView;
@Override
protected int initLayout() {
return R.layout.activity_vioce_progress;
}
@Override
protected void initView() {
voiceProgressView = findViewById(R.id.voice_progress);
Button play = findViewById(R.id.play);
AssetFileDescriptor fd;
try {
fd = getAssets().openFd("test.mp3");
voiceProgressView.configmusic().setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength());
if (voiceProgressView.initMusic()) {
Toast.makeText(this,"音乐载入成功",Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(this,"音乐载入失败",Toast.LENGTH_SHORT).show();
}
} catch (IOException e) {
e.printStackTrace();
}
play.setOnClickListener(v -> voiceProgressView.reset());
}
@Override
protected void onDestroy() {
voiceProgressView.destory();
super.onDestroy();
}
@Override
protected void initData() {
}
}
layout:voice_progress.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".view.voicePorgress.VioceProgressActivity">
<include
android:id="@+id/include2"
layout="@layout/title_include" />
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/grey"
android:layout_gravity="center"
android:layout_marginTop="180dp"
android:text="点击图案可进行播放"/>
<com.ui.design.view.voicePorgress.view.VoiceProgressView
android:id="@+id/voice_progress"
android:layout_width="250dp"
android:layout_gravity="center"
android:layout_height="40dp"
android:layout_marginTop="20dp"/>
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/play"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="40dp"
android:text="重置"/>
</LinearLayout>
项目代码仓库
如果直接复制可能会出现代码缺陷,完整代码请去仓库下载
如果觉得还行,耽误您几秒钟的时间去我的仓库点点star,万一以后用到了呢?