自定义View-贝塞尔曲线实现简单的波浪效果

(简单的效果图如上)

自定义的属性文件attrs_wave_view.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="WaveView">
        <attr name="wave_num" format="integer"/>
        <attr name="wave_len" format="dimension"/>
        <attr name="wave_color" format="color"/>
        <attr name="duration_time" format="integer"/>
    </declare-styleable>
</resources>

自定义view

public class WaveView extends View{
    private ValueAnimator mAnimator;

    private float mWidth;
    private float mHeight;
    private float mCenterY;

    private int mColor;//波浪的颜色
    private int mWaveNum;//波浪的个数
    private float mOffset=0;//偏移量
    private float mWaveLen;//一个波浪的长度
    private int mDuringTime;//持续的时间

    private Paint mWavePaint;
    private Path mWavePath;
    public WaveView(Context context) {
        this(context,null);
    }

    public WaveView(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

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

    //解析自定义属性
    private void initAttrs(Context context, AttributeSet attrs) {
        TypedArray typedArray=context.obtainStyledAttributes(attrs, R.styleable.WaveView);
        mColor=typedArray.getColor(R.styleable.WaveView_wave_color,Color.LTGRAY);
        mWaveNum=typedArray.getInt(R.styleable.WaveView_wave_num,2);
        mWaveLen=typedArray.getDimension(R.styleable.WaveView_wave_len,1000f);
        mDuringTime=typedArray.getInt(R.styleable.WaveView_duration_time,1000);
        typedArray.recycle();//释放资源
    }

    //初始化画笔路径
    private void init(){
        mWavePaint=new Paint(Paint.ANTI_ALIAS_FLAG);
        mWavePaint.setColor(mColor);
        mWavePaint.setStyle(Paint.Style.FILL_AND_STROKE);
        mWavePath=new Path();
    }

    //开启值动画
    private void startAnim() {
        mAnimator=ValueAnimator.ofFloat(0,mWaveLen);
        mAnimator.setRepeatCount(ValueAnimator.INFINITE);
        mAnimator.setDuration(mDuringTime);
        mAnimator.setInterpolator(new LinearInterpolator());
        mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mOffset= (float) animation.getAnimatedValue();
                postInvalidate();
            }
        });
        mAnimator.start();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mHeight=h;
        mWidth=w;
        mCenterY=h/2;
    }

    //绘制
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mWavePath.reset();
        mWavePath.moveTo(-mWaveLen+mOffset,mCenterY);
        for (int i=0;i<mWaveNum;i++){
            //(-mWaveLen / 4) + (i * mWaveLen)+mOffset和(i-1/4)*mWaveLen+mOffset
            //正弦曲线路径
            mWavePath.quadTo((-mWaveLen*3/4)+(i*mWaveLen)+mOffset,mCenterY+mWaveLen*0.06f,-0.5f*mWaveLen+(i*mWaveLen)+mOffset,mCenterY);
            mWavePath.quadTo((-mWaveLen / 4) + (i * mWaveLen)+mOffset,mCenterY-mWaveLen*0.06f,i*mWaveLen+mOffset,mCenterY);
        }
        mWavePath.lineTo(mWidth,mHeight);
        mWavePath.lineTo(0,mHeight);
        mWavePath.close();//闭合路径
        canvas.drawPath(mWavePath,mWavePaint);
    }

    //根据View是否显示来开启关闭值动画
    @Override
    protected void onWindowVisibilityChanged(int visibility) {
        super.onWindowVisibilityChanged(visibility);
        if (visibility==View.VISIBLE){
            if (mAnimator==null){
                startAnim();
            }
        }else {
            if (mAnimator!=null){
                mAnimator.end();
                mAnimator=null;
            }
        }
    }
}

使用

    <android.coolweather.com.myui.UI.WaveView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        x:wave_num="4"
        x:wave_len="250dip"
        x:wave_color="#fc9c9c"
        x:duration_time="1000"/>

猜你喜欢

转载自blog.csdn.net/start_mao/article/details/80411846