English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Audio Bar Chart
As shown in the figure below is this audio bar chart:
Since this is just a custom View usage, we will not actually listen to audio input, but simulate some numbers randomly.
If you want to implement a static audio bar chart like the one shown above, I believe you can find the idea very quickly, that is, to draw a series of rectangles, with a slight offset between each rectangle. The following code shows a method to calculate the coordinates.
for (int i = 0; i < mRectCount; i++) { // The drawing of the rectangle starts from the left side to the top, right, and bottom (the distance from the left edge of the canvas to the left and right edges, and the distance from the top edge of the canvas to the top and bottom edges) canvas.drawRect( (float) (mRectWidth * i + offset), currentHeight, (float) ( mRectWidth * (i + 1)) mRectHeight, mRectPaint ); }
As shown in the above code, we create these small rectangles through a loop, where currentHeight is the height of each small rectangle. By continuously offsetting the abscissa, these static small rectangles are drawn. Next, by randomly changing the height of the rectangles, we simulate audio, and directly use the Math.random() method to randomly change these heights and assign them to currentHeight, as shown in the following code.
// Since this is just a simple example, we do not listen to audio input and can simulate some numbers randomly mRandom = Math.random(); currentHeight = (float) (mRectHeight * mRandom);
This can achieve a static effect, but how to achieve a dynamic effect? In fact, it is also very simple, just call the invalidate() method in the onDraw() method to notify the View to redraw. However, there is no need to notify the View to redraw every time a new rectangle is drawn, as this would affect the effect due to the too fast refresh rate. Therefore, we can use the following code to delay the redrawing of the View, as shown below:
posInvalidateDelayed(300);
In this way, every300ms notify the View to redraw, and you can get a good visual effect. Finally, adding a gradient effect can make the View more realistic, as shown in the code below:
@Override protected void onSizeChanged(int w, int h, int oldW, int oldH) { super.onSizeChanged(w, h, oldW, oldH); // Gradient effect LinearGradient mLinearGradient; // The width of the canvas int mWidth; // Get the width of the canvas mWidth = getWidth(); // Get the maximum height of the rectangle mRectHeight = getHeight(); // Get the width of a single rectangle (the part subtracted is the spacing to the right boundary) mRectWidth = (mWidth-offset) / mRectCount; // Instantiate a linear gradient mLinearGradient = new LinearGradient( 0, 0, mRectWidth, mRectHeight, topColor, downColor, Shader.TileMode.CLAMP ); // Add the shader to the pen mRectPaint.setShader(mLinearGradient); }
From this example, we can know that when creating a custom View, we need to proceed step by step, starting from a basic effect and gradually adding features, drawing more complex effects. No matter how complex a custom View is, it is always a function that evolves gradually. So don't think that creating a custom View is very difficult. A journey of a thousand miles begins with a single step. As long as you start, you can get more and more skilled step by step.
Code
The following is the complete code for this time:
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; /** * Custom audio simulation bar chart * Created by shize on 2016/9/5. */ public class MyAF extends View { // Number of audio rectangles private int mRectCount; // Paint for the audio rectangle private Paint mRectPaint; // Two gradient colors private int topColor, downColor; // Width and height of the audio rectangle private int mRectWidth, mRectHeight; // Offset private int offset; // Frequency Speed 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){ // Store the attributes in the TypedArray TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.MyAF); mRectPaint = new Paint(); // Add the base color of the rectangle brush mRectPaint.setColor(ta.getColor(R.styleable.MyAF_AFTopColor, ContextCompat.getColor(context, R.color.top_color))); // Add the upper part of the rectangle gradient color topColor = ta.getColor(R.styleable.MyAF_AFTopColor, ContextCompat.getColor(context, R.color.top_color)); // Add the lower part of the rectangle gradient color downColor = ta.getColor(R.styleable.MyAF_AFDownColor, ContextCompat.getColor(context, R.color.down_color)); // Set the number of rectangles mRectCount = ta.getInt(R.styleable.MyAF_AFCount, 10); // Set the time interval for redrawing, which is also the speed of change mSpeed = ta.getInt(R.styleable.MyAF_AFSpeed, 300); // Interval between each rectangle offset = ta.getInt(R.styleable.MyAF_AFOffset, 5); // Recycle TypeArray ta.recycle(); } @Override protected void onSizeChanged(int w, int h, int oldW, int oldH) { super.onSizeChanged(w, h, oldW, oldH); // Gradient effect LinearGradient mLinearGradient; // The width of the canvas int mWidth; // Get the width of the canvas mWidth = getWidth(); // Get the maximum height of the rectangle mRectHeight = getHeight(); // Get the width of a single rectangle (the part subtracted is the spacing to the right boundary) mRectWidth = (mWidth-offset) / mRectCount; // Instantiate a linear gradient mLinearGradient = new LinearGradient( 0, 0, mRectWidth, mRectHeight, topColor, downColor, Shader.TileMode.CLAMP ); // Add the shader to the pen mRectPaint.setShader(mLinearGradient); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); double mRandom; float currentHeight; for (int i = 0; i < mRectCount; i++) { // Since this is just a simple example, we do not listen to audio input and can simulate some numbers randomly mRandom = Math.random(); currentHeight = (float) (mRectHeight * mRandom); // The drawing of the rectangle starts from the left side to the top, right, and bottom (the distance from the left edge of the canvas to the left and right edges, and the distance from the top edge of the canvas to the top and bottom edges) canvas.drawRect( (float) (mRectWidth * i + offset), currentHeight, (float) ( mRectWidth * (i + 1)) mRectHeight, mRectPaint ); } // This causes the view to redraw with a delay postInvalidateDelayed(mSpeed); } }
The complete code of the layout file:
<?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>
The above-mentioned is the Android implementation of the audio bar chart effect introduced by the editor for everyone (similar to audio animation without listening to audio input). I hope it will be helpful to everyone. If you have any questions, please leave a message, and the editor will reply to everyone in time. Thank you very much for everyone's support for the Yell Tutorial website!
Statement: The content of this article is from the Internet, and the copyright belongs to the original author. The content is contributed and uploaded by Internet users spontaneously. This website does not own the copyright, has not been manually edited, and does not assume any relevant legal liability. If you find any content suspected of copyright infringement, please send an email to: notice#oldtoolbag.com (Please replace # with @ when sending an email for reporting. Provide relevant evidence, and once verified, this site will immediately delete the content suspected of infringement.)