android 繪制波浪曲線

  1. 怎樣畫波浪

通過貝塞爾曲線

  1. 怎樣讓波,浪起來

讓波浪水平移動

  1. 保持讓波浪動起來時,一直正確顯示波浪

確保左側(cè)起點始終小于0,

//使用
final WaveView viewById = (WaveView) findViewById(R.id.bezier);
        viewById.post(new Runnable() {
            @Override
            public void run() {
                viewById.start();
            }
        });

實現(xiàn)思路

  1. Path配合rQuadTo畫出單個波浪的區(qū)域
  2. 畫出所有波浪,并且在控件不可視的范圍處(x < 0)處也添加上一個波浪
  3. 通過ValueAnimator不斷修改Path的左側(cè)起始位置dx,并且觸發(fā)重繪,ValueAnimator的取值范圍是負(fù)單個波浪寬度 - 0是為了確保動畫不會出現(xiàn)奇怪的位移
package com.example.a18.path.wave;

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.LinearInterpolator;

/**
 * desc: todo 描述本類功能
 * author: pdog
 * email: pdog@qq.com
 * time: 2017/11/8  12 :34
 */
public class WaveView extends View {

    private Paint mPaint;
    private Path mPath;
    private int mWidth;
    private int mHeight;

    public WaveView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }


    //當(dāng)前移動的距離
    float tranlateWidth;

    ValueAnimator mValueAnimator;


    private void init() {
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setColor(Color.BLUE);
        mPaint.setStrokeWidth(2);

        mPath = new Path();


    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        mValueAnimator = ValueAnimator.ofInt(0,1);
        mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                tranlateWidth = valueAnimator.getAnimatedFraction() * mWidth;
                invalidate();
                System.out.println("update...");
            }
        });
        mValueAnimator.setDuration(1 << 10);
        mValueAnimator.setInterpolator(new LinearInterpolator());
        mValueAnimator.setRepeatMode(ValueAnimator.RESTART);
        mValueAnimator.setRepeatCount(ValueAnimator.INFINITE);
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        mValueAnimator.cancel();
        mValueAnimator = null;
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        mWidth = getWidth();
        mHeight = getHeight();
        float waveHeight = (float) (mWidth / 5);


        mPath.moveTo(-mWidth, 0);

        mPath.rCubicTo(mWidth / 4 * 1, -waveHeight, mWidth / 4 * 3, waveHeight, mWidth, 0);
        mPath.rCubicTo(mWidth / 4 * 1, -waveHeight, mWidth / 4 * 3, waveHeight, mWidth, 0);

        mPath.rLineTo(0, mHeight >> 1);
        mPath.rLineTo(-mWidth << 1, 0);
        mPath.close();
    }

    public void start() {
        mValueAnimator.start();
    }

    @Override
    protected void onDraw(Canvas canvas) {

        canvas.translate(tranlateWidth, getHeight() >> 1);

        canvas.drawPath(mPath, mPaint);
    }
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容