Android 双曲线波浪动画(第一发)
2016-07-01 12:13
639 查看
前言:
好像是从简书看到一个IOS的双曲线波浪的动画,刚好最近把Cavans重新复习了一遍,那么就用这个来巩固好了,而且这个效果确实挺好玩的。如果大家对android中的三次贝塞尔曲线不太理解,对API也不太熟的,可以去这个博客看看[置顶] Android自定义控件三部曲文章索引,这是我读过总结的最详细的博文,很适合摸索阶段和温习阶段去阅读,这里感谢启舰大神,非常细致的博文。
上图:
![](https://img-blog.csdn.net/20160701114725684)
颜色搭配有点丑,wave的波长也不是很完美,大家将就着看下就是了,看是来看代码好了。
代码通杀一切:
DoubleWaveView
先看onDraw部分,其实只需要看其中一个wave的代码就OK了:
既然是画一条占满屏幕宽度的wave,肯定是使用rQuadTo这个API了,和quadTo的API绝对位置不同的是rQuadTo的参数都是相对位置的值,这个两个API我想还是稍微说下好了,看图:
![](https://img-blog.csdn.net/20160701115959472)
OK,说完了,有点粗糙和暴力,不过应该能看懂就是了,如果还是不懂,可以看开头介绍的那篇博客。
代码中
我整个wave的波长其实就是屏幕的宽度,所以我在画wave的时候小小的偷了个懒,因为我知道我想画的wave其实就是屏幕的三倍长,所以循环了三次,如果是不知道自己到底的wave的最终具体波长的可以这么写:
这里循环的意思,其实就是我从屏幕左侧一个波长的点开始,每次增长一个wave的长度,最后想要到达屏幕右侧一个波长的点。
OK,属性动画这里就不需要多讲了吧,很简单的一个值得变化,另外注意下,在MainActivity中,动态添加的时候需要,设置LayoutParams
这样一个很简单的双曲线动画就OK了,当然了我看到的双曲线动画,比这个要精致很多,那是下一篇博客的内容了。
好像是从简书看到一个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了,当然了我看到的双曲线动画,比这个要精致很多,那是下一篇博客的内容了。
相关文章推荐
- android-----事件分发机制测试系列(三)
- Android 代码中动态为RadioGroup添加RadioButton
- Android之四大组件之一-Activity(一)
- android6.0源码分析之Camera API2.0下的初始化流程分析
- 6.1、Android Studio的Android Monitor概览
- 6.1、Android Studio的Android Monitor概览
- Android之AsyncTask异步加载(二)
- 彻底理解android中的内部存储与外部存储
- Android Studio中的跨进程访问(aidl)
- Android仿IOS上拉下拉弹性效果
- Android 6.0 的运行时权限
- Android Listview嵌套viewpager 滑动冲突解决
- Android 代码当中动态改变某个控件的位置
- Android之AsyncTask异步加载的简介(一)
- android5.1 AsyncTask 启动慢
- Android开发笔记(一百零九)利用网盘实现云存储
- Android进程整理
- Android 监听器2
- Android 异常java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
- android 7.1 输入动态匹配