Android學習之使用貝塞爾曲線實現波紋效果

package com.lzy.host.perfect.view;

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;

/**
 * 波紋效果實現View
 */
public class WaveView extends View {

    //波浪畫筆
    private Paint mPaint;
    //測試紅點畫筆
    private Paint mCyclePaint;

    //波浪Path類
    private Path mPath;
    //一個波浪長度
    private int mWaveLength = 1000;
    //波紋個數
    private int mWaveCount;
    //平移偏移量
    private int mOffset;
    //波紋的中間軸
    private int mCenterY;

    //屏幕高度
    private int mScreenHeight;
    //屏幕寬度
    private int mScreenWidth;

    private ValueAnimator animator;

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

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

    public WaveView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.animator = ValueAnimator.ofInt(0, mWaveLength);
        mPath = new Path();
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setAntiAlias(true);
        mPaint.setColor(Color.BLUE);
        mPaint.setStrokeWidth(5);
        mPaint.setStyle(Paint.Style.STROKE);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mScreenHeight = h;
        mScreenWidth = w;
        //加1.5:至少保證波紋有2個,至少2個才能實現平移效果
        mWaveCount = (int) Math.round(mScreenWidth / mWaveLength + 1.5);
        mCenterY = mScreenHeight / 2;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mPath.reset();
        //移到屏幕外最左邊
        mPath.moveTo(-mWaveLength + mOffset, mCenterY);
        for (int i = 0; i < mWaveCount; i++) {
            //正弦曲線
            mPath.quadTo((-mWaveLength * 3 / 4) + (i * mWaveLength) + mOffset, mCenterY + 60, (-mWaveLength / 2) + (i * mWaveLength) + mOffset, mCenterY);
            mPath.quadTo((-mWaveLength / 4) + (i * mWaveLength) + mOffset, mCenterY - 60, i * mWaveLength + mOffset, mCenterY);
        }
        //填充矩形
//        mPath.lineTo(mScreenWidth, mScreenHeight);
//        mPath.lineTo(mScreenWidth + mWaveLength, mCenterY);
//        mPath.close();
        canvas.drawPath(mPath, mPaint);
    }

    public void start(long interval) {
        animator.setDuration(interval);
        animator.setRepeatCount(ValueAnimator.INFINITE);
        animator.setInterpolator(new LinearInterpolator());
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mOffset = (int) animation.getAnimatedValue();
                postInvalidate();
            }
        });
        animator.start();
    }

    public void stop() {
        if (this.animator != null) {
            this.animator.cancel();
        }
    }

}


package com.lzy.host.perfect.demo;

import android.os.Bundle;
import android.widget.TextView;

import com.lzy.host.perfect.R;
import com.lzy.host.perfect.activity.BaseActivity;
import com.lzy.host.perfect.view.WaveView;

/**
 * 波紋效果
 *
 * @author linzhiyong
 * @time 2017年1月16日17:07:18
 * @desc
 *
 */
public class WaveViewDemoActivity extends BaseActivity {

    private TextView topTitleView;

    private WaveView waveView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_wave_demo);
        topTitleView = (TextView) findViewById(R.id.base_top_title);
        topTitleView.setText("波紋效果");
        waveView = (WaveView) findViewById(R.id.waveView);
        waveView.start(1500);
    }

    @Override
    protected void onDestroy() {
        if (waveView != null) {
            waveView.stop();
        }
        super.onDestroy();
    }
}


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/main_gray"
    android:clipToPadding="true"
    android:fitsSystemWindows="true"
    android:orientation="vertical">

    <include layout="@layout/base_top_title" />

    <com.lzy.host.perfect.view.WaveView
        android:id="@+id/waveView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章