欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android实现音频条形图效果(仿音频动画无监听音频输入)

程序员文章站 2024-03-06 11:27:55
音频条形图 如下图所示就是这次的音频条形图: 由于只是自定义view的用法,我们就不去真实地监听音频输入了,随机模拟一些数字即可。 如果要实现一个如上图的静态音频...

音频条形图

如下图所示就是这次的音频条形图:

Android实现音频条形图效果(仿音频动画无监听音频输入)

由于只是自定义view的用法,我们就不去真实地监听音频输入了,随机模拟一些数字即可。

如果要实现一个如上图的静态音频条形图,相信大家应该可以很快找到思路,也就是绘制一个个的矩形,每个矩形之间稍微偏移一点距离即可。如下代码就展示了一种计算坐标的方法。

for (int i = 0; i < mrectcount; i++) {
// 矩形的绘制是从左边开始到上、右、下边(左右边距离左边画布边界的距离,上下边距离上边画布边界的距离)
canvas.drawrect(
(float) (mrectwidth * i + offset),
currentheight,
(float) ( mrectwidth * (i + 1)),
mrectheight,
mrectpaint
);
}

如上代码中,我们通过循环创建这些小的矩形,其中currentheight就是每个小矩形的高,通过横坐标的不断偏移,就绘制出了这些静态的小矩形。下面再通过矩形的高度随机变化模拟音频,这里直接利用math.randoom()方法来随机改变这些高度,并赋值给currentheight,代码如下所示。

// 由于只是简单的案例就不监听音频输入,随机模拟一些数字即可
mrandom = math.random();
currentheight = (float) (mrectheight * mrandom);

这样就能实现静态效果了,但是如何实现动态效果呢?其实也是非常简单的,只要在ondraw()方法中再去调用invalidate()方法通知view进行重绘就可以了。不过这里不需要每次一绘制完新的矩形就通知view进行重绘,这样会因为刷新速度太快反而影响效果。因此,我们可以使用如下代码来进行view的延迟重绘,代码如下:

posinvalidatedelayed(300);

这样每隔300ms通知view进行重绘,就可以得到一个比较好的视觉效果了。最后添加一个渐变效果可以使view更加逼真,代码如下所示:

@override
protected void onsizechanged(int w,int h,int oldw,int oldh) {
super.onsizechanged(w, h, oldw, oldh);
// 渐变效果
lineargradient mlineargradient;
// 画布的宽
int mwidth;
// 获取画布的宽
mwidth = getwidth();
// 获取矩形的最大高度
mrectheight = getheight();
// 获取单个矩形的宽度(减去的部分为到右边界的间距)
mrectwidth = (mwidth-offset) / mrectcount;
// 实例化一个线性渐变
mlineargradient = new lineargradient(
0,
0,
mrectwidth,
mrectheight,
topcolor,
downcolor,
shader.tilemode.clamp
);
// 添加进画笔的着色器
mrectpaint.setshader(mlineargradient);
}

从这个例子中,我们可以知道,在创建自定义view的时候,需要一步一步来,从一个基本的效果开始,慢慢地添加功能,绘制更复杂的效果。不论是多么复杂的自定义view都一定是慢慢迭代起来的功能,所以不要觉得自定义view有多难。千里之行始于足下,只要开始做,慢慢地就能越来越熟练。

代码

以下是这次的完整代码:

package com.example.customaf;
import android.content.context;
import android.content.res.typedarray;
import android.graphics.canvas;
import android.graphics.lineargradient;
import android.graphics.paint;
import android.graphics.shader;
import android.support.v4.content.contextcompat;
import android.util.attributeset;
import android.view.view;
import com.example.afanalog.r;
/**
* 自定义的音频模拟条形图
* created by shize on 2016/9/5.
*/
public class myaf extends view {
// 音频矩形的数量
private int mrectcount;
// 音频矩形的画笔
private paint mrectpaint;
// 渐变颜色的两种
private int topcolor, downcolor;
// 音频矩形的宽和高
private int mrectwidth, mrectheight;
// 偏移量
private int offset;
// 频率速度
private int mspeed;
public myaf(context context) {
super(context);
}
public myaf(context context, attributeset attrs) {
super(context, attrs);
setpaint(context, attrs);
}
public myaf(context context, attributeset attrs, int defstyleattr) {
super(context, attrs, defstyleattr);
setpaint(context, attrs);
}
public void setpaint(context context, attributeset attrs){
// 将属性存储到typedarray中
typedarray ta = context.obtainstyledattributes(attrs,r.styleable.myaf);
mrectpaint = new paint();
// 添加矩形画笔的基础颜色
mrectpaint.setcolor(ta.getcolor(r.styleable.myaf_aftopcolor,
contextcompat.getcolor(context, r.color.top_color)));
// 添加矩形渐变色的上面部分
topcolor=ta.getcolor(r.styleable.myaf_aftopcolor,
contextcompat.getcolor(context, r.color.top_color));
// 添加矩形渐变色的下面部分
downcolor=ta.getcolor(r.styleable.myaf_afdowncolor,
contextcompat.getcolor(context, r.color.down_color));
// 设置矩形的数量
mrectcount=ta.getint(r.styleable.myaf_afcount, 10);
// 设置重绘的时间间隔,也就是变化速度
mspeed=ta.getint(r.styleable.myaf_afspeed, 300);
// 每个矩形的间隔
offset=ta.getint(r.styleable.myaf_afoffset, 5);
// 回收typearray
ta.recycle();
}
@override
protected void onsizechanged(int w,int h,int oldw,int oldh) {
super.onsizechanged(w, h, oldw, oldh);
// 渐变效果
lineargradient mlineargradient;
// 画布的宽
int mwidth;
// 获取画布的宽
mwidth = getwidth();
// 获取矩形的最大高度
mrectheight = getheight();
// 获取单个矩形的宽度(减去的部分为到右边界的间距)
mrectwidth = (mwidth-offset) / mrectcount;
// 实例化一个线性渐变
mlineargradient = new lineargradient(
0,
0,
mrectwidth,
mrectheight,
topcolor,
downcolor,
shader.tilemode.clamp
);
// 添加进画笔的着色器
mrectpaint.setshader(mlineargradient);
}
@override
protected void ondraw(canvas canvas) {
super.ondraw(canvas);
double mrandom;
float currentheight;
for (int i = 0; i < mrectcount; i++) {
// 由于只是简单的案例就不监听音频输入,随机模拟一些数字即可
mrandom = math.random();
currentheight = (float) (mrectheight * mrandom);
// 矩形的绘制是从左边开始到上、右、下边(左右边距离左边画布边界的距离,上下边距离上边画布边界的距离)
canvas.drawrect(
(float) (mrectwidth * i + offset),
currentheight,
(float) ( mrectwidth * (i + 1)),
mrectheight,
mrectpaint
);
}
// 使得view延迟重绘
postinvalidatedelayed(mspeed);
}
}

布局文件的完整代码:

<?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:custom="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.afanalog.mainactivity">
<com.example.customaf.myaf
android:layout_width="match_parent"
android:layout_height="match_parent"
custom:afcount="15"
custom:afdowncolor="@color/down_color"
custom:afspeed="300"
custom:aftopcolor="@color/top_color"
custom:afoffset="15"
/>
</linearlayout>

以上所述是小编给大家介绍的android实现音频条形图效果(仿音频动画无监听音频输入),希望对大家有所帮助