效果图: 

                                

android 录音柱形 android录音波浪纹_三角函数

       

android 录音柱形 android录音波浪纹_android 录音柱形_02

1.绘制录音曲线效果

  1. 公式和网站介绍 我们要绘制这种效果,最直观方便的方式就是采用三角函数的cos/sin的函数,首先我们需要一个重要的网站:
    Desmos: https://www.desmos.com/calculator 可以把我们的三角函数以图刑的方式显示,公式:y=Asin(ωx+φ)+k
    例如:
  2. 衰减函数选择

    虽然我们得到了图形,但是效果好像不是我们需要的,所有需要修改,这里介绍一个重要的概念:衰减函数 而且是对称衰减 对应效果图:

android 录音柱形 android录音波浪纹_三角函数_03

  1. 其中  是我们选择的衰减函数,这样我们就得到了逐渐增加 和 减弱的波形效果。
    转化成代码:
private float getSinPoint(float x) {

        return (float) (4/(4+Math.pow(x,4))*Math.sin(3*x + 5*offset));
    }
  1. offset 看第三处相位变化,参数可以根据自己需要修改
  2. 修改相位,让曲线动起来
    虽然我们得到了,想要的波形但是怎么让他动起来呢,我们知道公式:y=Asin(ωx+φ)+k 其中 φ 是改变相位的,也就是我们只要动态的修改这个值,我们就能得到不同位置的图形

如图我们可以动态的拖动修改 a 这个值,看到图形也在移动。
1.获取采样数据,我们能看到整个衰减过程,从-4 到 4 之间变化明显,我们就取这段值作为采样数据

List<Float> mSimples = new ArrayList<>();

    /**
     * 采样图像中就有变化的数据【-4,4】这是x值
     */
    private void simple() {
        ValueAnimator animator = ValueAnimator.ofFloat(-4, 4);
        animator.setDuration(1500);
        animator.setInterpolator(new LinearInterpolator());
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mSimples.add((float) animation.getAnimatedValue());
                invalidate();
            }
        });
        animator.start();
    }

2.根据采样的x值,计算相应的 y 值并且用path路径封装,等待绘制

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.translate(getWidth()/2,getHeight()/2);

        mPath.reset();
        for (int i = 0;i<mSimples.size();i++){
            if (i==0){
                mPath.moveTo(mSimples.get(i)*130,getSinPoint(mSimples.get(i))*100);
            }else {
                mPath.lineTo(mSimples.get(i)*130,getSinPoint(mSimples.get(i))*100);
            }
        }
        canvas.drawPath(mPath,mPaint);
    }

其中x,y乘以130和100是为了放大在手机界面的效果,这里只是做个简单的放大,主要为了demo方便,真正项目上要根据分辨率来。
3.修改 offset 相位让曲线移动

float offset = 0;
    ValueAnimator mAnimator;
    private void startAnimation(){

        mAnimator = ValueAnimator.ofFloat(0, (float) (2*Math.PI));
        mAnimator.setDuration(5000);
        mAnimator.setInterpolator(new LinearInterpolator());
        mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                offset = (float) animation.getAnimatedValue();
                invalidate();
            }
        });
    }

这里用个属性动画修改 三角函数的移动,我们知道一个三角函数的周期 是 2π,所以这里只需要取一个周期內就行。

所以分析到这里基本原理我们都明白了,也有代码实现,需要作成多复杂的,就自己去发挥发挥就行了。

github:https://github.com/WangRain1/AnimationLine

2.让字体迎波而浪

通过绘制录音波浪我们能够把波浪曲线绘制出来并且能动起来,接下来我们要做的是要把我们的字体,给放到曲线上并且让字体也能和曲线一样浪浪的~~

  1. 选择合适的波浪曲线

效果图:

android 录音柱形 android录音波浪纹_android 录音柱形_04

波动不用太大,让字体有浮动的效果就行,看起来舒服,转化成代码:

private float getSinPoint(float x) {

        return (float) (4/(4+Math.pow(x,2))*Math.sin(0.2*x + offset));
    }

其他就和绘制录音波浪一样,这里就不累赘了,下面提一个Path的方法

  1. canves绘制text 到 path上 
/**
     * Draw the text, with origin at (x,y), using the specified paint, along the specified path. The
     * paint's Align setting determins where along the path to start the text.
     *
     * @param text The text to be drawn
     * @param path The path the text should follow for its baseline
     * @param hOffset The distance along the path to add to the text's starting position
     * @param vOffset The distance above(-) or below(+) the path to position the text
     * @param paint The paint used for the text (e.g. color, size, style)
     */
    public void drawTextOnPath(@NonNull String text, @NonNull Path path, float hOffset,
            float vOffset, @NonNull Paint paint) {
        super.drawTextOnPath(text, path, hOffset, vOffset, paint);
    }

通过这个方法可以实现把我们的字体绘制到path上。

canvas.drawTextOnPath("w a n g  r a i n 1",mPath,200,0,mPaint);

200是x坐标的偏移量,y坐标偏移量为0。

至此就结束了,整个绘制流程。Github:https://github.com/WangRain1/AnimationLine