亲手撸一个录音分贝波浪图展示view

效果图

最近做到这个需求,在网上找不到类似的就自己撸了一个

1.首先获取录音的分贝值

 private void updateMicStatus() {
        if(recorder != null && isRecord) {
            int ratio = recorder.getMaxAmplitude() / BASE;
            int db = 0;// 分贝
            if(ratio > 1)
                db = (int) (20 * Math.log10(ratio));
            final double finalDb = db;
            activity.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    ((VoiceWave) activity.findViewById(R.id.videoView)).setDecibel((int) finalDb);
                }
            });
            mHandler.postDelayed(mUpdateMicStatusTimer, SPACE);
        }
    }

2.创建数据源

private void initData(int decibel) {
        int quietDecibel;
        if(isHeadSetOn) {
            quietDecibel = 70;//耳机比较敏感
        } else {
            quietDecibel = 60;
        }
        boolean isQuiet;
        if(decibel < quietDecibel) {
            isQuiet = true;
        } else {
            isQuiet = false;
        }
        int base = (int) ((decibel-quietDecibel) / 30f * 100);//quietDecibel是最低分贝 40是最高90分贝-50分贝,90是基数区间0-90的最大值
        if(base < 0) {
            base = 0;
        }
        Logger.i(TAG, "分贝:"+decibel);
        if(dataList != null) {
            dataList.clear();
        }
        dataList.add(new Bean(1, 20, 30));
        dataList.add(new Bean(2, 20, 30));
        dataList.add(new Bean(3, isQuiet ? 30 : base+35, 20));//v
        dataList.add(new Bean(4, 20, 30));
        dataList.add(new Bean(5, 30, isQuiet ? 20 : base+20));
        dataList.add(new Bean(6, isQuiet ? 20 : base+20, 30));//v
        dataList.add(new Bean(7, 30, isQuiet ? 20 : base+20));//v
        dataList.add(new Bean(8, isQuiet ? 20 : base+50, 30));//10
        dataList.add(new Bean(9, 20, isQuiet ? 30 : base+30));
        dataList.add(new Bean(10, isQuiet ? 20 : base+20, 30));//
        dataList.add(new Bean(11, 30, isQuiet ? 20 : base+50));//35
        dataList.add(new Bean(12, isQuiet ? 20 : base+50, 30));//50
        //-----------------------------------------------------
        dataList.add(new Bean(13, 30, isQuiet ? 20 : base+70));//70
        //-----------------------------------------------------
        dataList.add(new Bean(14, isQuiet ? 20 : base+50, 30));//50
        dataList.add(new Bean(15, 30, isQuiet ? 20 : base+50));//35
        dataList.add(new Bean(16, isQuiet ? 20 : base+20, 30));//35
        dataList.add(new Bean(17, 20, isQuiet ? 30 : base+30));
        dataList.add(new Bean(18, isQuiet ? 20 : base+50, 30));//20
        dataList.add(new Bean(19, 30, isQuiet ? 20 : base+20));//50
        dataList.add(new Bean(20, isQuiet ? 20 : base+20, 30));//20
        dataList.add(new Bean(21, 30, isQuiet ? 20 : base+20));//20
        dataList.add(new Bean(22, 20, 30));
        dataList.add(new Bean(23, isQuiet ? 30 : base+35, 20));
        dataList.add(new Bean(24, 20, 30));//20
        dataList.add(new Bean(25, 20, 30));
    }

3.绘制wave

        根据分贝值循环绘制每一帧,比如说话的分贝值是80,那么在获取分贝值的回调里就会持续传入80给view,在这里绘制,把这个80分成四段,第一段绘制最短的(20),然后次短(40),次长(60),最长(80),绘制四次形成动画,

        那么当分贝持续变化的时候,音浪也就波动出现啦

@Override
    protected void onDraw(final Canvas canvas) {
        super.onDraw(canvas);
        Resources resources = getContext().getResources();
        DisplayMetrics displayMetrics = resources.getDisplayMetrics();
        float rate = displayMetrics.scaledDensity;
        int baseX = getMeasuredWidth() / 2-((7+3) * 25 / 2);
        canvas.translate(0, getMeasuredHeight() / 2);
        for(int i = 0; i < dataList.size(); i++) {
            final Bean bean = dataList.get(i);
            //间隔间距
            int grep = 10;
            if(flag1) {//2 6  绘制次短
                int m1 = (int) (bean.getShortV() * heightRate+((bean.getLongV() * heightRate-bean.getShortV() * heightRate) / 3));
                canvas.drawLine(baseX+grep * i, m1 / 2 / 2f * rate, baseX+grep * i, -m1 / 2 / 2f * rate, paint);
                if(i == dataList.size()-1) {
                    flag1 = false;
                }
            } else {//
                if(flag2) {//3 5   绘制次长
                    if(i == dataList.size()-1) {
                        flag2 = false;
                        if(!flag3) {
                            flag1 = true;
                        }
                    }
                    int m2 = (int) (bean.getLongV() * heightRate-((bean.getLongV() * heightRate-bean.getShortV() * heightRate) / 3));
                    canvas.drawLine(baseX+grep * i, m2 / 2 / 2f * rate, baseX+grep * i, -m2 / 2 / 2f * rate, paint);
                } else {
                    if(flag3) {//4  绘制最长
                        if(i == dataList.size()-1) {
                            flag3 = false;
                            flag2 = true;
                        }
                        canvas.drawLine(baseX+grep * i, bean.getLongV() * heightRate / 2 / 2f * rate, baseX+grep * i, -bean.getLongV() * heightRate / 2 / 2f * rate, paint);
                    } else {//1 7  绘制最短
                        canvas.drawLine(baseX+grep * i, bean.getShortV() * heightRate / 2 / 2f * rate, baseX+grep * i, -bean.getShortV() * heightRate / 2 / 2f * rate, paint);
                        if(i == dataList.size()-1) {
                            flag3 = true;
                            flag2 = true;
                            flag1 = true;
                        }
                    }
                }
            }
        }
    }

------------------------免费的demo地址---------------------

发布了13 篇原创文章 · 获赞 2 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/tan6458/article/details/105663794