English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
音频条形图
如下图所示就是这次的音频条形图:
由于只是自定义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에서 오디오 바 차트 효과(오디오 입력을 감지하지 않는 오디오 애니메이션 모방)로, 여러분께 도움이 되길 바랍니다. 어떤 질문이나 의문이 있으면 댓글을 남겨 주세요. 편집자는 즉시 답변을 드리겠습니다. 또한, 얼라우 강의 사이트에 대한 여러분의 지지에 깊이 감사드립니다!
언급된 내용은 인터넷에서 가져온 것으로, 저작권자가 소유하고 있으며, 인터넷 사용자가 자발적으로 기여하고 자체로 업로드한 내용입니다. 이 사이트는 소유권을 가지지 않으며, 인공 편집 처리를 하지 않았으며, 관련 법적 책임을 부담하지 않습니다. 저작권 문제가 있는 내용을 발견하면 이메일을 보내 주시기 바랍니다.: notice#oldtoolbag.com(이메일을 보내면, #을 @으로 변경하십시오. 신고하고 관련 증거를 제공하십시오. 실제로 확인되면, 이 사이트는 즉시 의심스러운 저작권 내용을 제거합니다.)