音频跳动的View--FrequencyView

本文记录了开发一个名为FrequencyView的Android自定义视图的过程,该视图能显示音频波动效果。视图允许自定义柱形条的数量、宽度、颜色、波动节奏和间隙。在开发中,作者面临了没有具体数据输入的挑战,但通过创建Wave对象封装波动逻辑,简化了代码。文章提供了完整FrequencyView的代码实现,易于理解和使用。
摘要由CSDN通过智能技术生成

开年来公司不忙,就在闲逛时朋友说给写给小控件,并给出这样的效果:
我问他还要什么要求,提供的数据是什么,他竟然告诉我没要求,数据随机给就行。我的第一反应是这还不简单啊,就写个view简单画一下不就好了,于是上来就开写,但是写着写着发现还是有些麻烦,麻烦点就在他竟然不给数据。下面在这个控件编写过程记录下来。


效果如下:

首先看到这样一个效果时,需要确定这个view哪些属性支持定制。我给出的自定义属性包括:柱形条个数,柱形条宽度,柱形条颜色(支持设置颜色组),波动节奏快慢,柱形条间隙(由控件宽度、柱形条个数、柱形条宽度共同决定)。

于是控件有了如下属性:

    /**
     * 单根柱形宽度,默认为10
     */
    private int pillarWidth = 10;

    /**
     * 柱形数量,默认为4
     */
    private int pillarAmount = 4;

    /**
     * 柱形颜色
     */
    private int pillarColor = Color.rgb(179, 100, 53);

    /**
     * 波动节奏
     * 快-慢 0-1
     */
    private double rhythm = 0.5;

    /**
     * 柱形颜色组,
     * 当pillarColors等于pillarAmount时,对应柱形取pillarColors对应颜色
     * 当pillarColors大于pillarAmount时,对应柱形取pillarColors前pillarAmount个对应颜色
     * 当pillarColors小于pillarAmount时,pillarColors循环拼接后,对应柱形取pillarColors对应颜色
     */
    private int[] pillarColors;
开始画view前需要确定view大小:
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //设置控件宽度
        setMeasuredDimension(measureWidth(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec));
        //控件内容宽度
        contentWidth = getWidth() - getPaddingLeft() - getPaddingRight();
        //控件内容高度
        contentHight = getHeight() - getPaddingTop() - getPaddingBottom();
        //控件的左、上、右、下坐标
        left = getPaddingLeft();
        top = getPaddingTop();
        right = getWidth() - getPaddingRight();
        bottom = getHeight() - getPaddingBottom();

        //柱形条间隙
        gap = pillarAmount > 1 ? (float) (contentWidth - pillarAmount * pillarWidth) / (float) (pillarAmount - 1) : 0;
        
        //初始化属性动画值数组
        this.animValues = new float[pillarAmount];
        //初始化波动实体数组
        this.waves = new Wave[pillarAmount];
        for (int i = 0; i < waves.length; i++)
        {
            int distance = (int) (Math.random() * contentHight);
            waves[i] = new Wave(-1, distance, bottom, bottom - distance);
        }
    }

    /**
     * 计算控件宽度
     * @param measureSpec
     * @return
     */
    private int measureWidth(int measureSpec)
    {
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);
        //根据柱形数量跟宽度计算出最小宽度
        int minWidth = pillarWidth * pillarAmount + getPaddingLeft() + getPaddingRight();
        if (specMode == MeasureSpec.EXACTLY)
        {
            return specSize > minWidth ? specSize : minWidth;
        }
        return minWidth;
    }
21行animValues用来记录每个柱形条属性动画的动画值;

23行waves用来记录每次波动的波动情况情况;

25-28行为waves赋初始值(柱形条都在最低端,都向上运动,运动范围都为控件的内容区域高度contentHight)。


下面看一下Wave对象:

    /**
     * 波动实体类
     */
    class Wave
    {
        /**
         * 波动
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值