一、动态音频播放柱形图
1、效果图:
2、步骤
(1)、新建自定义View类,继承View
(2)、重写onDraw()方法,使用画笔和画布循环画一定数量的柱形
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//画柱形
for (int i = 0; i < 10; i++){
float mRandom = (float) Math.random();
float currentHeight = mRectHeight*mRandom;
canvas.drawRect((float) (mWidth*0.4/2+mRectWidth * i +offset),currentHeight, (float) (mWidth*0.4/2+mRectWidth*(i+1)),mRectHeight,mPaint1);
}
postInvalidateDelayed(800);
}
(3)、重写onSizeChange()方法,实现柱形的渐变效果
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
//实现音频柱的渐变效果
mWidth = getWidth();
mRectHeight = getHeight();
mRectWidth = (int) (mWidth*0.6/10);
mLinearGradient = new LinearGradient(
0,0,mRectWidth,mRectHeight,Color.YELLOW,Color.BLUE, Shader.TileMode.CLAMP);
mPaint1.setShader(mLinearGradient);
}
(4)、在适合的xml布局文件中引入即可
<com.example.test.MyView1
android:id="@+id/myView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@+id/text"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
附:全部代码如下:
package com.example.test;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.Nullable;
public class MyView1 extends View {
Paint mPaint1; //画笔
int mWidth = 200;
int mHeight = 1000;
int mRectWidth = 30; //柱形的宽度
int mRectHeight = 200; //柱形的高度
int offset = 5; //柱形之间的距离
LinearGradient mLinearGradient;
public MyView1(Context context) {
super(context);
init();
}
public MyView1(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public MyView1(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init(){
//初始化画笔和画笔的颜色、样式等
mPaint1 = new Paint();
mPaint1.setColor(getResources().getColor(R.color.purple_200));
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//画柱形
for (int i = 0; i < 10; i++){
float mRandom = (float) Math.random();
float currentHeight = mRectHeight*mRandom;
canvas.drawRect((float) (mWidth*0.4/2+mRectWidth * i +offset),currentHeight, (float) (mWidth*0.4/2+mRectWidth*(i+1)),mRectHeight,mPaint1);
}
postInvalidateDelayed(800);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
//实现音频柱的渐变效果
mWidth = getWidth();
mRectHeight = getHeight();
mRectWidth = (int) (mWidth*0.6/10);
mLinearGradient = new LinearGradient(
0,0,mRectWidth,mRectHeight,Color.YELLOW,Color.BLUE, Shader.TileMode.CLAMP);
mPaint1.setShader(mLinearGradient);
}
}
二、自定义大小的圆形
1、效果图
一个圆形
2、步骤
(1)新建自定义View类,继承View
(2)可设置自定义属性
public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//自定义属性
TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.MyView);
mColor = a.getColor(R.styleable.MyView_circle_color,Color.RED);
a.recycle();
init();
}
values文件下面新建attrs.xml,可设置颜色,后续可设置给画笔
public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//自定义属性
TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.MyView);
mColor = a.getColor(R.styleable.MyView_circle_color,Color.RED);
a.recycle();
init();
}
(3)重写onMeasure(),自定义绘制大小
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//宽测量模式
int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
//宽测量大小
int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
//高测量模式
int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
//高测量大小
int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
if (widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST){
setMeasuredDimension(200,200);
}else if (widthSpecMode == MeasureSpec.AT_MOST){
setMeasuredDimension(200,heightSpecSize);
}else if (heightSpecMode == MeasureSpec.AT_MOST){
setMeasuredDimension(widthSpecSize,200);
}else{
setMeasuredDimension(widthMeasureSpec,heightMeasureSpec);
}
}
(4)重写onDraw()方法画圆形
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int width = getWidth()-getPaddingLeft()-getPaddingLeft();
int height = getHeight()-getPaddingLeft()-getPaddingLeft();
int radius = Math.min(width,height)/2;
canvas.drawCircle((float) width/2+getPaddingLeft(),(float) height/2+getPaddingLeft(),radius,paint);
}
(5)相应地方调用需注意设置wrap_content,因为想实现重写onDraw方法中的效果,需要自己支持wrap_content,并且padding也需要自己处理。
<com.example.test.MyView
android:id="@+id/myView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
app:layout_constraintTop_toBottomOf="@+id/text"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
附:全部代码
package com.example.test;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import androidx.annotation.Nullable;
public class MyView extends View {
public int mColor = Color.RED;
private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
public MyView(Context context) {
super(context);
init();
}
public MyView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//自定义属性
TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.MyView);
mColor = a.getColor(R.styleable.MyView_circle_color,Color.RED);
a.recycle();
init();
}
//初始化画笔
private void init(){
paint.setColor(mColor);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//宽测量模式
int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
//宽测量大小
int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
//高测量模式
int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
//高测量大小
int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
if (widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST){
setMeasuredDimension(200,200);
}else if (widthSpecMode == MeasureSpec.AT_MOST){
setMeasuredDimension(200,heightSpecSize);
}else if (heightSpecMode == MeasureSpec.AT_MOST){
setMeasuredDimension(widthSpecSize,200);
}else{
setMeasuredDimension(widthMeasureSpec,heightMeasureSpec);
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int width = getWidth()-getPaddingLeft()-getPaddingLeft();
int height = getHeight()-getPaddingLeft()-getPaddingLeft();
int radius = Math.min(width,height)/2;
canvas.drawCircle((float) width/2+getPaddingLeft(),(float) height/2+getPaddingLeft(),radius,paint);
}
}