CommentVoiceLineView.java 4.45 KB
package com.wd.speech.view;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.View;

import com.wd.speech.R;


/**
 * @author LiuKun
 * @date 2023/5/2  16:40
 * @Description:语音录入
 */
public class CommentVoiceLineView extends View {

    private int voiceLineColor = Color.BLACK;
    private Paint paintVoiceLine;
    /**
     * 灵敏度
     */
    private int sensibility = 4;

    private float maxVolume = 100;


    private float translateX = 0;
    private boolean isSet = false;

    /**
     * 振幅
     */
    private float amplitude = 1;
    /**
     * 音量
     */
    private float volume = 10;
    private int fineness = 1;
    private float targetVolume = 1;

    private long lastTime = 0;
    private int lineSpeed = 90;

    private Path path1;
    private Path path2;

    private boolean isStart = false;

    public CommentVoiceLineView(Context context) {
        super(context);
    }

    public CommentVoiceLineView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public CommentVoiceLineView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    @SuppressLint("ResourceType")
    private void init(Context context) {
        voiceLineColor = context.getResources().getColor(R.color.res_color_C10);
        maxVolume = 50;
        sensibility = 4;
        lineSpeed = 90;
        fineness = 1;

        path1 = new Path();
        path2 = new Path();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        drawVoiceLine(canvas);
        run();
    }

    private void lineChange() {
        if (lastTime == 0) {
            lastTime = System.currentTimeMillis();
            translateX += 1.5;
        } else {
            if (System.currentTimeMillis() - lastTime > lineSpeed) {
                lastTime = System.currentTimeMillis();
                translateX += 1.5;
            } else {
                return;
            }
        }
        if (volume < targetVolume && isSet) {
            volume += getHeight() / 30;
        } else {
            isSet = false;
            if (volume <= 10) {
                volume = 10;
            } else {
                if (volume < getHeight() / 30) {
                    volume -= getHeight() / 60;
                } else {
                    volume -= getHeight() / 30;
                }
            }
        }
    }

    private void drawVoiceLine(Canvas canvas) {

        lineChange();
        if (paintVoiceLine == null) {
            paintVoiceLine = new Paint();
            paintVoiceLine.setColor(voiceLineColor);
            paintVoiceLine.setAntiAlias(true);
            paintVoiceLine.setStyle(Paint.Style.STROKE);
            paintVoiceLine.setStrokeWidth(2);
        }
        canvas.save();
        int moveY = getHeight() / 2;

        path1.reset();
        path1.moveTo(getWidth(), getHeight() / 2);

        if (!isStart) {
            path1.lineTo(0, getHeight() / 2);
            canvas.drawPath(path1, paintVoiceLine);
            return;
        }

        for (float i = getWidth() - 1; i >= 0; i -= fineness) {
            amplitude = 4 * volume * i / getWidth() - 4 * volume * i * i / getWidth() / getWidth();
            float sin = amplitude * (float) Math.sin((i - 53.36) * Math.PI / 180 - translateX);
            path1.lineTo(i, (2 * sin - 3 * sin / 4 + moveY));
        }
        canvas.drawPath(path1, paintVoiceLine);


        path2.reset();
        path2.moveTo(getWidth(), getHeight() / 2);
        for (float i = getWidth() - 1; i >= 0; i -= fineness) {
            amplitude = 4 * volume * i / getWidth() - 4 * volume * i * i / getWidth() / getWidth();
            float sin = amplitude * (float) Math.sin((i - 53.36) * Math.PI / 180 - translateX);
            path2.lineTo(i, getHeight() - (2 * sin - 3 * sin / 4 + moveY));
        }
        canvas.drawPath(path2, paintVoiceLine);


        canvas.restore();
    }

    public void setVolume(int volume) {
        isStart = true;
        if (volume > maxVolume * sensibility / 25) {
            isSet = true;
            this.targetVolume = getHeight() * volume / 2 / maxVolume;
        }
    }

    public void stop() {
        isStart = false;
        run();
    }

    public void run() {
        invalidate();
    }

}