Android自定义View(三)波浪WaveView

2018-08-03  本文已影响101人  digtal_
2189443-077edb8e8af3b743.gif

实现效果图:


ezgif-1-3ff5a394a9.gif
ezgif-1-2b22b908cc.gif

在Android开发中,系统已经帮我们封装好了二阶和三阶的对应实现方法,我们只管调用就行

1.初始化,设置了三个点分别是起始点,控制点和结束点

    private void init(Context context) {
        WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics displayMetrics = new DisplayMetrics();
        manager.getDefaultDisplay().getMetrics(displayMetrics);
        int screenWidth = displayMetrics.widthPixels;
        int screenHeight = displayMetrics.heightPixels;
        mStartPx = screenWidth / 8;
        mStartPy = screenHeight * 3 / 4;
        mEndPx = screenWidth * 7 / 8;
        mEndPy = screenHeight * 3 / 4;
        mControlPx = screenWidth / 2;
        mControly = screenHeight / 3;

        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setColor(Color.BLACK);
        mPaint.setStrokeWidth(2);
        mPaint.setTextSize(30);
        mPaint.setStyle(Paint.Style.STROKE);
        mTextBond = new RectF();
        mPath = new Path();
    }

2.先画二条线段起始点到控制点和控制点到结束点的线段

 canvas.drawLine(mStartPx, mStartPy, mControlPx, mControly, mPaint);
 canvas.drawLine(mControlPx, mControly, mEndPx, mEndPy, mPaint);

3.然后画贝塞尔曲线

 mPaint.setStrokeWidth(2);
 mPath.moveTo(mStartPx,mStartPy);
 mPath.quadTo(mControlPx,mControly,mEndPx,mEndPy);
 canvas.drawPath(mPath,mPaint);

完整代码:

 @Override
    protected void onDraw(Canvas canvas) {
        //重置路径
        mPath.reset();
        //画线段
        canvas.drawLine(mStartPx, mStartPy, mControlPx, mControly, mPaint);
        canvas.drawLine(mControlPx, mControly, mEndPx, mEndPy, mPaint);
        float textWidth = mPaint.measureText("起始点");
        //画文字
        canvas.drawText("起始点", mStartPx - textWidth / 2, mStartPy + textWidth, mPaint);
        canvas.drawText("控制点", mControlPx - textWidth / 2, mControly - textWidth, mPaint);
        canvas.drawText("结束点", mEndPx - textWidth / 2, mEndPy + textWidth, mPaint);
        //画点
        mPaint.setColor(Color.BLUE);
        mPaint.setStrokeWidth(20);
        canvas.drawPoint(mStartPx,mStartPy,mPaint);
        canvas.drawPoint(mControlPx,mControly,mPaint);
        canvas.drawPoint(mEndPx,mEndPy,mPaint);
        //画贝塞尔曲线
        mPaint.setStrokeWidth(2);
        mPath.moveTo(mStartPx,mStartPy);
        mPath.quadTo(mControlPx,mControly,mEndPx,mEndPy);
        canvas.drawPath(mPath,mPaint);
    }

4.在onTouchevent中动态改变控制点的位置:

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                mControlPx = (int) event.getX();
                mControly = (int) event.getY();
                invalidate();
                break;
            case MotionEvent.ACTION_MOVE:
                mControlPx = (int) event.getX();
                mControly = (int) event.getY();
                invalidate();
                break;

        }
        return true;
    }

波浪View的实现,原理就是利用动画逐步移动path

   public class WaveView extends View {
    private Paint mPaint;
    private Path mPath;
    private int mScreenWidth;
    private int mScreenHeight;
    private int offset;


    public WaveView(Context context) {
        this(context, null);
    }

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

    private void init(Context context) {
        WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics displayMetrics = new DisplayMetrics();
        manager.getDefaultDisplay().getMetrics(displayMetrics);
        mScreenWidth = displayMetrics.widthPixels;
        mScreenHeight = displayMetrics.heightPixels;

        mPaint = new Paint();
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setAntiAlias(true);
        mPaint.setColor(Color.CYAN);
        mPaint.setStrokeWidth(4);
        mPath = new Path();
        doanim();
    }

    private void doanim() {
        ValueAnimator va = ValueAnimator.ofInt(0, mScreenWidth);
        va.setRepeatCount(ValueAnimator.INFINITE);
        va.setDuration(1000);
        va.setInterpolator(new LinearInterpolator());
        va.start();
        va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                int value = (int) animation.getAnimatedValue();
                offset = value;
                invalidate();
            }
        });

    }

    @Override
    protected void onDraw(Canvas canvas) {
        mPath.reset();

        mPath.moveTo(-mScreenWidth + offset, mScreenHeight / 2);
        mPath.quadTo(-mScreenWidth * 3 / 4 + offset, mScreenHeight / 2 - 100, -mScreenWidth / 2 + offset, mScreenHeight / 2);
        mPath.quadTo(-mScreenWidth / 4 + offset, mScreenHeight / 2 + 100,  offset, mScreenHeight / 2);
        mPath.quadTo(mScreenWidth  / 4 + offset, mScreenHeight / 2 - 100,  mScreenWidth  / 2 + offset, mScreenHeight / 2);
        mPath.quadTo(mScreenWidth * 3 / 4 + offset, mScreenHeight / 2 + 100,mScreenWidth + offset, mScreenHeight / 2);

        mPath.lineTo(mScreenWidth, mScreenHeight);
        mPath.lineTo(0, mScreenHeight);
        canvas.drawPath(mPath, mPaint);
    }


}
上一篇下一篇

猜你喜欢

热点阅读