Android开发之Path的高级用法用贝塞尔曲线绘制波浪线

前言:贝塞尔曲线分为一级曲线,二级曲线,三级曲线和多级曲线,利用贝塞尔曲线可以做出很多有意思的动画和图形,今天我们就来实现一个比较简单的波浪线。

-----------------分割线---------------

初步认识贝塞尔曲线:

mPath.moveTo:设置起点。

mPath.rQuadTo:绘制曲线。

注意:第二个mPath.rQuadTo相对于自己的起始点--也即是上一个曲线的终点。

mPath.lineTo:闭合。

我们也可以使用path.quadTo(x1, y1, x2, y2)绘制二级贝塞尔曲线。

ok看完整代码:

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.view.View;

/**
 * Created by Fly on 2017/6/14.
 */

public class MyView extends View {

    Paint mPaint;
    Path mPath;

    public MyView(Context context) {
        super(context);
        mPaint = new Paint();
        mPaint.setColor(Color.RED);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(10);
        mPath = new Path();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mPath.moveTo(100, 400);
        mPath.rQuadTo(100, -150, 200, 0);
        mPath.rQuadTo(100, 150, 200, 0);
        mPath.lineTo(100, 400);
        canvas.drawPath(mPath, mPaint);
    }
}
效果图:


---------------分割线---------------

扫描二维码关注公众号,回复: 8588302 查看本文章

如果想画动态的波浪线,需要我们不断的改变起点,废话不说直接看代码:

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.util.AttributeSet;
import android.view.View;
import android.view.animation.LinearInterpolator;

import java.util.Random;

/**
 * Created by Fly on 2017/6/13.
 */

public class WaveView2 extends View {

    private Paint mPaint;
    private Path mPath;
    private int mWaveLength = 100;
    private int dx;
    private int dy;

    public WaveView2(Context context) {
        super(context);
        init();
    }

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

    private void init() {
        mPaint = new Paint();
        mPaint.setColor(Color.RED);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(10);
        mPath = new Path();
    }

    int s = 50;

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mPath.reset();
        int originY = 300;
        int mWaveHalfLength = mWaveLength / 2;
        mPath.moveTo(-mWaveLength + dx, originY);

        int max = 60;
        int min = 40;
        int maxW = 120;
        int minW = 80;
        Random random = new Random();
        try {
            Thread.sleep(500);
            s = random.nextInt(max) % (max - min + 1) + min;
            mWaveLength = random.nextInt(maxW) % (maxW - minW + 1) + minW;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }


        //屏幕的宽度里面放多少个波长
        for (int i = -mWaveLength; i < getWidth() + mWaveLength; i += mWaveLength) {
            //相对绘制二阶贝塞尔曲线(相对于自己的起始点--也即是上一个曲线的终点  的距离dx1)
            mPath.rQuadTo(mWaveHalfLength / 2, -s, mWaveHalfLength, 0);
            mPath.rQuadTo(mWaveHalfLength / 2, s, mWaveHalfLength, 0);
            //			path.quadTo(x1, y1, x2, y2)
        }
        //颜色填充
        //画一个封闭的空间
//        mPath.lineTo(getWidth(), getHeight());
//        mPath.lineTo(0, getHeight());
//        mPath.close();

        canvas.drawPath(mPath, mPaint);
    }

    public void startAnimation() {
        ValueAnimator animator = ValueAnimator.ofInt(0, mWaveLength);
        animator.setDuration(1000);
        animator.setInterpolator(new LinearInterpolator());
        //无限循环
        animator.setRepeatCount(ValueAnimator.INFINITE);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                dx = (int) animation.getAnimatedValue();
                postInvalidate();
            }
        });
        animator.start();
    }
}
然后在MainActivity中开启动画:
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        WaveView2 waveView = (WaveView2) findViewById(R.id.wv);
        waveView.startAnimation();
    }
}
布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">


    <com.fly.lsn35_waveview.WaveView2
        android:id="@+id/wv"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>
效果:


---------------------完-----------------

发布了105 篇原创文章 · 获赞 74 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/qq_32306361/article/details/73252788