Android 双曲线波浪动画(第一发)

来源:互联网 发布:类似于沙盘的软件 编辑:程序博客网 时间:2024/04/29 07:04

前言:
好像是从简书看到一个IOS的双曲线波浪的动画,刚好最近把Cavans重新复习了一遍,那么就用这个来巩固好了,而且这个效果确实挺好玩的。如果大家对android中的三次贝塞尔曲线不太理解,对API也不太熟的,可以去这个博客看看[置顶] Android自定义控件三部曲文章索引,这是我读过总结的最详细的博文,很适合摸索阶段和温习阶段去阅读,这里感谢启舰大神,非常细致的博文。

上图:

这里写图片描述

颜色搭配有点丑,wave的波长也不是很完美,大家将就着看下就是了,看是来看代码好了。

代码通杀一切:
DoubleWaveView

package cjh.doublewave;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;/** * Created by chenjiahuan on 16/7/1. */public class DoubleWaveView extends View {    private Paint mPaint;    private Path mPath;    private int width, height;    private int dx;    public DoubleWaveView(Context context, int width, int height) {        super(context);        this.width = width;        this.height = height;        init();    }    public DoubleWaveView(Context context, AttributeSet attrs) {        super(context, attrs);    }    public DoubleWaveView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }    private void init() {        mPath = new Path();        mPaint = new Paint();        mPaint.setStyle(Paint.Style.FILL_AND_STROKE);    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        mPath.reset();        mPaint.setColor(Color.parseColor("#65ff0000"));        mPath.moveTo(-width + dx, height / 5 * 4);        for (int i = 0; i < 3; i++) {            mPath.rQuadTo(width / 4, -70, width / 2, 0);            mPath.rQuadTo(width / 4, 70, width / 2, 0);        }        mPath.lineTo(width, height);        mPath.lineTo(0, height);        mPath.close();        canvas.drawPath(mPath, mPaint);        mPath.reset();        mPaint.setColor(Color.parseColor("#6500ff00"));        mPath.moveTo(-width + dx, height / 5 * 4);        for (int i = 0; i < 3; i++) {            mPath.rQuadTo(width / 4, 70, width / 2, 0);            mPath.rQuadTo(width / 4, -70, width / 2, 0);        }        mPath.lineTo(width, height);        mPath.lineTo(0, height);        mPath.close();        canvas.drawPath(mPath, mPaint);    }    public void startAnimation() {        ValueAnimator valueAnimator = ValueAnimator.ofInt(0, width);        valueAnimator.setDuration(2000);        valueAnimator.setRepeatCount(ValueAnimator.INFINITE);        valueAnimator.setInterpolator(new LinearInterpolator());        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                dx = (int) animation.getAnimatedValue();                invalidate();            }        });        valueAnimator.start();    }}

先看onDraw部分,其实只需要看其中一个wave的代码就OK了:

mPath.reset();        mPaint.setColor(Color.parseColor("#65ff0000"));        mPath.moveTo(-width + dx, height / 5 * 4);        for (int i = 0; i < 3; i++) {            mPath.rQuadTo(width / 4, -70, width / 2, 0);            mPath.rQuadTo(width / 4, 70, width / 2, 0);        }        mPath.lineTo(width, height);        mPath.lineTo(0, height);        mPath.close();        canvas.drawPath(mPath, mPaint);

既然是画一条占满屏幕宽度的wave,肯定是使用rQuadTo这个API了,和quadTo的API绝对位置不同的是rQuadTo的参数都是相对位置的值,这个两个API我想还是稍微说下好了,看图:

这里写图片描述

OK,说完了,有点粗糙和暴力,不过应该能看懂就是了,如果还是不懂,可以看开头介绍的那篇博客。

代码中mPath.moveTo(-width + dx, height / 5 * 4);这一行x轴的起始点不是固定的,dx是跟着属性动画走的,如果不清楚属性动画可以看我的文章Android动画-Property Animation(一),在博文的最后稍微介绍了抛物线的动画,其实就是使用的拦截器,一个道理。

我整个wave的波长其实就是屏幕的宽度,所以我在画wave的时候小小的偷了个懒,因为我知道我想画的wave其实就是屏幕的三倍长,所以循环了三次,如果是不知道自己到底的wave的最终具体波长的可以这么写:

if(int i = -wavewidth; i<= screenwidth + wavewidth; i+=wavewidth ){}

这里循环的意思,其实就是我从屏幕左侧一个波长的点开始,每次增长一个wave的长度,最后想要到达屏幕右侧一个波长的点。

OK,属性动画这里就不需要多讲了吧,很简单的一个值得变化,另外注意下,在MainActivity中,动态添加的时候需要,设置LayoutParams

 private void initWaveView() {        rootView = (FrameLayout) findViewById(R.id.rootView);        waveView = new DoubleWaveView(this, width, height);        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(width, height);        rootView.addView(waveView, params);        waveView.startAnimation();    }

这样一个很简单的双曲线动画就OK了,当然了我看到的双曲线动画,比这个要精致很多,那是下一篇博客的内容了。

0 0
原创粉丝点击