Android进阶系列:八、自定义View之音频抖动动效

这篇具有很好参考价值的文章主要介绍了Android进阶系列:八、自定义View之音频抖动动效。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

####绘制矩形抖动
我们要绘制音频抖动的效果,矩形的高度肯定不能一样,而是要根据声音的大小来显示,这里我们没有声音,简单模拟一下给高度乘上for循环里的i效果如图:
android抖动效果,Android程序员,android,音视频,windows
至此我们已经知道了如何绘制多个矩形,并控制不同的高度,那我们要如何动态的控制高度呢?比如我们点击开始录音的时候,就会动态的传入声音的大小,这个分贝值控制着矩形的抖动。要实现这个动态的效果,我们需要不断的设置分贝,并不断的刷新。所以我们可以开启一个线程,不断设置音量的分贝,并不断的刷新。为了让矩形抖动有错落感,就需要让每个矩形抖动的值不一样,所以我们设置一个list存储音量值,并依次改变里面的值即可。

private static final int MIN_WAVE_HEIGHT = 2;//矩形线最小高
private static final int MAX_WAVE_HEIGHT = 12;//矩形线最大高
private static final int[] DEFAULT_WAVE_HEIGHT = {2, 2, 2, 2};
private static final int UPDATE_INTERVAL_TIME = 100;//100ms更新一次
private LinkedList mWaveList = new LinkedList<>();
private float maxDb;

private void resetView(List list, int[] array) {
list.clear();
for (int anArray : array) {
list.add(anArray);
}
}

private synchronized void refreshElement() {
Random random = new Random();
maxDb = random.nextInt(5) + 2;
int waveH = MIN_WAVE_HEIGHT + Math.round(maxDb * (MAX_WAVE_HEIGHT - MIN_WAVE_HEIGHT));
mWaveList.add(0, waveH);
mWaveList.removeLast();
}

public boolean isStart = false;

private class LineJitterTask implements Runnable {
@Override
public void run() {
while (isStart) {
refreshElement();
try {
Thread.sleep(updateSpeed);
} catch (Exception e) {
e.printStackTrace();
}
postInvalidate();
}
}
}

public synchronized void startRecord() {
isStart = true;
executorService.execute(task);
}

public synchronized void stopRecord() {
isStart = false;
mWaveList.clear();
resetView(mWaveList, DEFAULT_WAVE_HEIGHT);
postInvalidate();
}

1.为了控制矩形抖动的范围,我们需要设置一个最大值和最小值。
2.并利用数组设置矩形的默认值,因为有四个矩形,所以数组大小为4
3.定义一个分贝值,控制矩形的高度
4.重置View的时候把默认的数组传进去,就可以达到View的重置,比如View的初始化,和停止录音的时候
5.刷新元素方法,用于不停的刷新矩阵的高度,让矩阵抖起来。这里用随机数模拟声音大小,传给数组,每次都添加到第一个,然后每次都移除最后一个,这样能让矩阵按顺序抖动。
6.在线程中调用这个刷新矩阵的方法,当开始录音的时候,在while中刷新矩阵,并睡眠100ms,这样就实现了没100ms刷新一次view,开始录音的时候设置isStart为true。
7.在停止录音的时候设置isStart为false,并初始化矩形为原始高度。由于在线程中刷新View,应该使用postInvalidate()方法。

至此这个逻辑已经实现了,稍微润色一下即可实现录音时的音频抖动
效果如图:

完整代码:

/**

  • 语音录制的动画效果
    */
    public class LineWaveVoiceView extends View {
    private static final String DEFAULT_TEXT = " 请录音 ";
    private static final int LINE_WIDTH = 9;//默认矩形波纹的宽度,9像素, 原则上从layout的attr获得
    private Paint paint = new Paint();
    private Runnable task;
    private ExecutorService executorService = Executors.newCachedThreadPool();
    private RectF rectRight = new RectF();//右边波纹矩形的数据,10个矩形复用一个rectF
    private RectF rectLeft = new RectF();//左边波纹矩形的数据
    private String text = DEFAULT_TEXT;
    private int updateSpeed;
    private int lineColor;
    private int textColor;
    private float lineWidth;
    private float textSize;

public LineWaveVoiceView(Context context) {
super(context);
}

public LineWaveVoiceView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}

public LineWaveVoiceView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView(attrs, context);
resetView(mWaveList, DEFAULT_WAVE_HEIGHT);
task = new LineJitterTask();
}

private void initView(AttributeSet attrs, Context context) {
//获取布局属性里的值
TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.LineWaveVoiceView);
lineColor = mTypedArray.getColor(R.styleable.LineWaveVoiceView_voiceLineColor, context.getColor(R.color.defaultLineColor));
lineWidth = mTypedArray.getDimension(R.styleable.LineWaveVoiceView_voiceLineWidth, LINE_WIDTH);
textSize = mTypedArray.getDimension(R.styleable.LineWaveVoiceView_voiceTextSize, 42);
textColor = mTypedArray.getColor(R.styleable.LineWaveVoiceView_voiceTextColor, context.getColor(R.color.defaultTextColor));
updateSpeed = mTypedArray.getColor(R.styleable.LineWaveVoiceView_updateSpeed, UPDATE_INTERVAL_TIME);
mTypedArray.recycle();
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//获取实际宽高的一半
int widthCentre = getWidth() / 2;
int heightCentre = getHeight() / 2;
paint.setStrokeWidth(0);
paint.setColor(textColor);
paint.setTextSize(textSize);
float textWidth = paint.measureText(text);
canvas.drawText(text, widthCentre - textWidth / 2, heightCentre - (paint.ascent() + paint.descent()) / 2, paint);

//设置颜色
paint.setColor(lineColor);
//填充内部
paint.setStyle(Paint.Style.FILL);
//设置抗锯齿
paint.setAntiAlias(true);
for (int i = 0; i < 10; i++) {
rectRight.left = widthCentre + textWidth / 2 + (1 + 2 * i) * lineWidth;
rectRight.top = heightCentre - lineWidth * mWaveList.get(i) / 2;
rectRight.right = widthCentre + textWidth / 2 + (2 + 2 * i) * lineWidth;
rectRight.bottom = heightCentre + lineWidth * mWaveList.get(i) / 2;

//左边矩形
rectLeft.left = widthCentre - textWidth / 2 - (2 + 2 * i) * lineWidth;
rectLeft.top = heightCentre - mWaveList.get(i) * lineWidth / 2;
rectLeft.right = widthCentre - textWidth / 2 - (1 + 2 * i) * lineWidth;

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
android抖动效果,Android程序员,android,音视频,windows
android抖动效果,Android程序员,android,音视频,windows
android抖动效果,Android程序员,android,音视频,windows
android抖动效果,Android程序员,android,音视频,windows

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
android抖动效果,Android程序员,android,音视频,windows

最后

我见过很多技术leader在面试的时候,遇到处于迷茫期的大龄程序员,比面试官年龄都大。这些人有一些共同特征:可能工作了5、6年,还是每天重复给业务部门写代码,工作内容的重复性比较高,没有什么技术含量的工作。问到这些人的职业规划时,他们也没有太多想法。

其实30岁到40岁是一个人职业发展的黄金阶段,一定要在业务范围内的扩张,技术广度和深度提升上有自己的计划,才有助于在职业发展上有持续的发展路径,而不至于停滞不前。

不断奔跑,你就知道学习的意义所在!

android抖动效果,Android程序员,android,音视频,windows

《Android高级架构师面试指导+2021大厂面试真题》免费领取

android抖动效果,Android程序员,android,音视频,windows

[外链图片转存中…(img-IfcqTDPI-1710828589258)]

《Android高级架构师面试指导+2021大厂面试真题》免费领取

[外链图片转存中…(img-bcyhFmgl-1710828589259)]文章来源地址https://www.toymoban.com/news/detail-857927.html

到了这里,关于Android进阶系列:八、自定义View之音频抖动动效的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android 自定义View 之 圆环进度条

      很多时候我们会使用进度条,而Android默认的进度条是长条的,从左至右。而在日常开发中,有时候UI为了让页面更美观,就需要用到圆环进度条,那么本文就是通过自定义写一个圆环进度条,首先看一下效果图:   关于自定义View的基础知识就不再做过多的讲解了,我

    2024年02月10日
    浏览(47)
  • Android:绘制自定义View人脸识别框

    项目开发需要自定义View实现一个人脸框,代码实现很平常,一些细节记录一下,方便以后查阅。 代码实现: FaceView.java 注意: 这里我把FaceView的layout_width、layout_height都设置成了\\\"match_parent\\\" 这里面有个 坑 容易踩到 本次开发时,xml中FaceView控件往上一直到第一层父布局宽、高

    2024年02月09日
    浏览(64)
  • Android 自定义View之圆形进度条

    很多场景下都用到这种进度条,有的还带动画效果, 今天我也来写一个。 写之前先拆解下它的组成: 底层圆形 上层弧形 中间文字 那我们要做的就是: 绘制底层圆形; 在同位置绘制上层弧形,但颜色不同; 在中心点绘制文本,显示进度。 按照这个目标,学习下自定义Vi

    2024年02月09日
    浏览(44)
  • Android 自定义View 之 Dialog弹窗

      在日常开发中用到弹窗是比较多的,常用于提示作用,比如错误操作提示,余额不足提示,退出登录提示等,还有用于数据展示的弹窗,上拉弹窗等等,主要为了简化在日常开发中的使用。   Android中的Dialog弹窗是一种用于展示特定信息或者在用户需要进行某些操作时

    2024年02月16日
    浏览(43)
  • Android自定义View之游戏摇杆键盘实现(一),快手android面试经验

    public class RemoteViewBg { private Bitmap bitmapBg; public RemoteViewBg(Bitmap bitmap) { bitmapBg = bitmap; } //背景的绘图函数 public void draw(Canvas canvas, Paint paint, Rect src0 ,Rect dst0 ) { canvas.drawBitmap(bitmapBg, src0, dst0, paint); } } 重写系统的触摸时间,判断触摸点在背景范围内还是背景范围外 @Override public b

    2024年04月12日
    浏览(46)
  • Android-高级-UI-进阶之路-(二)-深入理解-Android-8-0-View-触摸事件分发机制,查漏补缺

    我们看到内部又调用了父类 dispatchTouchEvent 方法, 所以最终是交给 ViewGroup 顶级 View 来处理分发了。 顶级 View 对点击事件的分发过程 在上一小节中我们知道了一个事件的传递流程,这里我们就大致在回顾一下。首先点击事件到达顶级 ViewGroup 之后,会调用自身的 dispatchTouchE

    2024年04月14日
    浏览(70)
  • [Android]自定义RecyclerView中View的动画

    官方有一个默认Item动画类DafaultItemAnimator,其中 DefaultItemAnimator 继承了SimpleItemAnimator 继承了 RecyclerView.ItemAnimator SimpleItemAnimator 它是一个包装类,用来判断当前的ViewHolder到底是执行移动、移除、添加或者改变等行为。 DefaultItemAnimator 是执行具体动画类,它负责将viewHolder初始化

    2024年02月11日
    浏览(66)
  • Android进阶 View事件体系(三):典型的滑动冲突情况和解决策略

    本篇文章为总结View事件体系的第三篇文章,前两篇文章的在这里: Android进阶 View事件体系(一):概要介绍和实现View的滑动 Android进阶 View事件体系(二):从源码解析View的事件分发 本篇文章主要是介绍两种基本的滑动冲突情况和对应的解决策略,内容有: 基本的滑动冲突

    2024年02月10日
    浏览(38)
  • Android自定义View之游戏摇杆键盘实现(一)

    public class RemoteViewBg { private Bitmap bitmapBg; public RemoteViewBg(Bitmap bitmap) { bitmapBg = bitmap; } //背景的绘图函数 public void draw(Canvas canvas, Paint paint, Rect src0 ,Rect dst0 ) { canvas.drawBitmap(bitmapBg, src0, dst0, paint); } } 重写系统的触摸时间,判断触摸点在背景范围内还是背景范围外 @Override public b

    2024年04月17日
    浏览(54)
  • Android 自定义View实战—制作一个简易输入框

    这次我们来做一个简易输入框,可以用于密码输入和验证码输入。 依然在EasyView中进行创建,在 com.easy.view 下新建一个 EasyEditText ,继承自 View ,实现里面的构造方法。 ① 构造方法 然后我们继承自 View ,重写里面的构造方法,代码如下: 下面就可以增加样式了。 ② XML样式

    2024年02月10日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包