首页 AI人工智能 APP源码

Android贝塞尔曲线-波纹(波浪)效果

Android贝塞尔曲线-波纹效果

刚写一个波纹的控件,具体的代码给上,简要介绍下实现的方法。

 

画图分析

 
如上图绿色方框为手机的屏幕,我们只需要在屏幕的前方再画一个相同的周期视图,然后将整个的画的曲线向右平移,最多平移到原点,也就是将ac段曲线移动到屏幕中间,然后重复这个步骤就可以得到一个类似于波浪的效果。这个周期用的就是ValueAnimator。
 

源代码

/**
 * Created by zhanghs on 2017/12/4/004.
 */
 
public class RippleView extends View {
    private int mWidth,mHeight;//画布的宽带和高度
    private float cycleWidth,cycleHeight=60f;//周期的宽度和高度
    private Path pathRipple;//画的路径
    private Paint paintRipple;//画笔
    private float moveSet=0;//移动的值
    private ValueAnimator animator;//动画
    private boolean isStart=false;
    public RippleView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initPaint();
        initAnimator();
    }
 
    /**
     * 初始化动画
     */
    private void initAnimator() {
        animator=ValueAnimator.ofFloat(0,mWidth);
        animator.setRepeatCount(ValueAnimator.INFINITE);
        animator.setDuration(1500);
        animator.setInterpolator(new LinearInterpolator());
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                moveSet= (float) valueAnimator.getAnimatedValue();
                invalidate();
            }
        });
    }
 
    /**
     * 初始化画的路径
     */
    private void initPath() {
        pathRipple=new Path();
        pathRipple.moveTo(-6*cycleWidth+moveSet,0);
        pathRipple.quadTo(-5*cycleWidth+moveSet,cycleHeight,-4*cycleWidth+moveSet,0);
        pathRipple.quadTo(-3*cycleWidth+moveSet,-cycleHeight,-2*cycleWidth+moveSet,0);
        pathRipple.quadTo(-cycleWidth+moveSet,cycleHeight,moveSet,0);
        pathRipple.quadTo(cycleWidth+moveSet,-cycleHeight,2*cycleWidth+moveSet,0);
        pathRipple.lineTo(2*cycleWidth+moveSet,mHeight/2);
        pathRipple.lineTo(-6*cycleWidth+moveSet,mHeight/2);
        pathRipple.close();
        pathRipple.setFillType(Path.FillType.WINDING);
    }
 
    /**
     * 初始化画笔
     */
    private void initPaint() {
        paintRipple=new Paint();
        paintRipple.setStrokeWidth(2);
        paintRipple.setStyle(Paint.Style.FILL);
        paintRipple.setColor(Color.BLUE);
        paintRipple.setAntiAlias(true);
    }
 
    /**
     * 画波纹
     * @param canvas
     */
    private void drawRipple(Canvas canvas) {
        initPath();
        canvas.drawPath(pathRipple,paintRipple);
    }
 
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mHeight=h;
        mWidth=w;
        cycleWidth=mWidth/4;
        initAnimator();
    }
 
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.translate(mWidth/2,mHeight/2);
        drawRipple(canvas);
    }
 
    /**
     * 开始动画
     */
    public void start(){
        if(isStart) return;
        isStart=true;
        if(animator==null){
            initAnimator();
        }
        animator.start();
    }
 
    /**
     * 结束动画
     */
    public void stop(){
        if(!isStart) return;
        isStart=false;
        moveSet=0;
        animator.cancel();
        animator=null;
        invalidate();
    }
}