Android 仿微信语音聊天音量大小显示控件

来源:互联网 发布:python与量化投资 编辑:程序博客网 时间:2024/05/13 16:18

某日用微信语音功能聊天,发现当我使用语音功能时,会弹出一个窗口,窗口中间有一个控件会实时的显示我说话声音的大小(即分贝)。当时觉得挺好玩,决定也仿制一个,效果如下
这里写图片描述
分析控件显示效果,可判断左边是一个imgview,右边是一个可以根据实时音量大小绘制梯度显示的自定义view。那就先解决这个自定义view。
我们可以把这个自定义view看成是一个上宽下窄的梯形,而且在纵向上等间距的着墨绘制。用一张图或许可以更好的表示。
这里写图片描述
上图是一个在笛卡尔坐标系中的梯形图,上底下底平行于X轴,startX对应的点是斜线的出发点,斜线在x轴方向上的偏移量mDx与y轴上偏移量mDy的关系mDx=K*mDy;mDyFill对应的区域是着墨区,mDyEmpty对应的是空白区,且mDy=mDyFill+mDyEmpty.我们可以通过修改以上数值进而修改着墨的区域。因为该自定义view不会在多处使用,所以不设置自定义属性,直接在代码中修改。贴下部分代码:

        //dp转px        mStartX= DensityUtils.dp2px(context,10);        mDx = DensityUtils.dp2px(context,4);//mDy=3*mDx        mDyFill = DensityUtils.dp2px(context,8);        mDyEmpty = DensityUtils.dp2px(context,4);        mDy=mDyEmpty+mDyFill;

我们可以把着墨区域看成是从一个完整梯形从下至上等间距截取下来的,因为实时音量分贝(音量大小单位)的不同,截取的次数mCurNum也会不同。接下来是绘制相关的代码

@Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        mWidth = getMeasuredWidth();        mHeight = getMeasuredHeight();        //可以绘制的着墨区域的最大数        int numDesignY=mHeight/mDy;        int numDesignX=(mWidth-mStartX)/mDx;        mNumMax = Math.min(numDesignX,numDesignY);        //init pen        mPaint.setColor(Color.BLACK);        mPaint.setStyle(Paint.Style.FILL);        mPaint.setAntiAlias(true);        mPaint.setStrokeWidth(1);        //绘制多边形        Path path=null;        for (int i = 0; i < mCurNum; i++) {            path=new Path();            path.moveTo(0,mHeight-i*(mDy));            path.lineTo(0,mHeight-(mDyFill+i*(mDy)));            path.lineTo(mStartX+i*mDx+mDx,mHeight-(mDyFill+i*(mDy)));            path.lineTo(mStartX+i*mDx,mHeight-i*(mDy));            path.close();            canvas.drawPath(path,mPaint);        }    }

采用命令模式更新mCurNum的值,令自定义view实现如下接口:

/**     * 分贝百分比监听,默认初始值为60,最大值90     */    public interface FractionListener{        /**         * 传入当前增长分贝的百分比进度         * @param curFraction         */        public void updateFraction(double curFraction);    }

实现接口

/**     * 设置当前可描绘层数,then 重绘     */    @Override    public void updateFraction(double curFraction) {        mCurNum = (int) (curFraction*mNumMax);        postInvalidate();    }

检测当前分贝后调用FractionListener.updateFraction方法,实现随分贝大小重新绘制。
关于如何获取android麦克风分贝的大小,请参考http://blog.csdn.net/pcaxb/article/details/47808675,感谢博主的文章。
如果你觉得这篇文章对你有用,那么赞一个吧<3<3 。
源码下载

原创粉丝点击