自定义View之动态音频条

本文介绍了如何自定义View来创建动态音频条效果。通过绘制一系列矩形并利用Math.random()生成随机高度,配合postInvalidateDelayed实现每隔0.3秒重绘。文中详细解释了canvas.drawRect()方法的参数含义,并展示了如何添加LinearGradient渐变效果,使得不同高度的矩形呈现多彩渐变。最后提供了完整代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上一篇文章主要介绍了如何对现有的控件进行拓展,即继承已有的某个view,这一篇文章将介绍如何自定义view,如何重写view。

先看一下demo图
这里写图片描述

思路很简单,就是绘制一个个的矩形,每个矩形之间稍微偏移一点距离即可。

 @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        for (int i = 0; i < mRectCount; i++) {
            mRandom = Math.random();
            float currentHeight = (float) (mRectHeight * mRandom);
            canvas.drawRect(
                    (mRectWidth * i+offset),
                    currentHeight,
                    (mRectWidth * (i + 1)),
                    mRectHeight,
                    mPaint);
        }
        postInvalidateDelayed(300);
    }

其中,currentHeight就是每个小矩形的高,通过横坐标的不断偏移,就绘制出了一个个静态的小矩形。每个小矩形的高通过Math.random()的方法来随机改变这些高度值,在通过postInvalidateDelayed(300),每隔0.3秒通知View进行重绘。

这里需要注意一点的就是画矩形的问题,canvas.drawRect的前4个参数到底是什么意思,一开始我一直没弄清楚,以为要画的矩形是在一个坐标轴的右边,所有的数据都是距离原点的距离,但是这显然是错误的,正确的应该使用android坐标系和视图坐标系(以原点向右为X的正方向,以原点向下是Y轴的正方向),这里的4个参数主要是根据手机屏幕,确切的说是父控件而言:
第一个和第三个参数是距离父控件的左边的距离
第二个个第四个参数是距离父控件的上端的距离

盗用别人的一张图说明一下:
这里写图片描述
这里是canvas.drawRect(150,75,260,120);

另外,再给绘制的Paint对象增加一个LinearGradient渐变效果,这样不同高度的矩形就会有不同颜色的渐变效果。
代码如下:

@Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mWidth = getWidth();
        mRectHeight = getHeight();
        mRectWidth = mWidth/mRectCount;
        mLinearGradient = new LinearGradient( 0,
                0,
                mRectWidth,
                mRectHeight,
                Color.YELLOW,
                Color.BLUE,
                Shader.TileMode.CLAMP);
        mPaint.setShader(mLinearGradient);
    }

最后,贴出全部代码:

package com.example.cntvuser.myapplication.common;

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;

/**
 * User: Picasso(380643397@qq.com)
 * Date: 2015-11-09
 * Time: 10:37
 * FIXME
 */
public class VolumeView extends View {
    private int mWidth;
    private int mRectWidth;
    private int mRectHeight;
    private Paint mPaint;
    private int mRectCount;
    private int offset = 5;//间隔
    private double mRandom;
    private LinearGradient mLinearGradient;

    public VolumeView(Context context) {
        super(context);
        initView();
    }

    public VolumeView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

    public VolumeView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView();
    }

    private void initView(){
        mPaint = new Paint();
        mPaint.setColor(Color.BLUE);
        mPaint.setStyle(Paint.Style.FILL);
        mRectCount = 8;
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mWidth = getWidth();
        mRectHeight = getHeight();
        mRectWidth = mWidth/mRectCount;
        mLinearGradient = new LinearGradient( 0,
                0,
                mRectWidth,
                mRectHeight,
                Color.YELLOW,
                Color.BLUE,
                Shader.TileMode.CLAMP);
        mPaint.setShader(mLinearGradient);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        for (int i = 0; i < mRectCount; i++) {
            mRandom = Math.random();
            float currentHeight = (float) (mRectHeight * mRandom);
            canvas.drawRect(
                    (mRectWidth * i+offset),
                    currentHeight,
                    (mRectWidth * (i + 1)),
                    mRectHeight,
                    mPaint);
        }
        postInvalidateDelayed(300);
    }
}

当我看完这个的时候,我想之前分享的MPAndroidChart绘制图表应该自己也会绘制了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值