Android自定义动画酷炫的提交按钮
今天开始记录工作中遇到的需要实现的动画效果实现自定义view动画,后期会有一些列动画设计思路的文章。
在这里分享的是设计实现思路,仅供学习使用,让大家拿到稍微复杂点的动画的时候要知道该如何去一步步分解实现,而不是抱怨
下边就先来看看设计需要的效果图及我们最终实现的效果图,毕竟有图有真相嘛!
圆角矩形绘制完成之后就是改变圆角半径的大小使其两边形成半圆的效果,那么怎么才能让他成为半圆呐,来看看一张图,若要绘制成半圆效果,那么这个圆的直径就是view自身的高度,那么这个圆的半径就是height/2
private void set_rect_to_angle_animation() { animator_rect_to_angle = ValueAnimator.ofInt(0, height / 2); animator_rect_to_angle.setDuration(duration); animator_rect_to_angle.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { circleAngle = (int) animation.getAnimatedValue(); invalidate();添加动画之后的效果如下
private void set_rect_to_circle_animation() { animator_rect_to_square = ValueAnimator.ofInt(0, default_two_circle_distance); animator_rect_to_square.setDuration(duration); animator_rect_to_square.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { two_circle_distance = (int) animation.getAnimatedValue(); //在靠拢的过程中设置文字的透明度,使文字逐渐消失的效果 int alpha = 255 - (two_circle_distance * 255) / default_two_circle_distance; textPaint.setAlpha(alpha); invalidate();完成上边代码后再来看下效果
private void set_move_to_up_animation() { final float curTranslationY = this.getTranslationY(); animator_move_to_up = ObjectAnimator.ofFloat(this, "translationY", curTranslationY, curTranslationY - move_distance); animator_move_to_up.setDuration(duration); animator_move_to_up.setInterpolator(new AccelerateDecelerateInterpolator());第四步:在圆中绘制一个对勾,而且是带动画的对勾,让对勾以动画的形式慢慢绘制出来
如果对相关API不熟悉的话不知道会怎么去实现呐,或许你会想通过绘制线的方式,在对勾起点开始不断改变移动点的坐标进行绘制,那么怎么获取这些点的坐标呐,这里我们使用Path和DashPathEffect两个方法实现,对DashPathEffect不了解的小伙伴可以去查一下文档哦
DashPathEffect这个类的作用就是将Path的线段虚线化。
构造函数为DashPathEffect(float[] intervals, float offset),其中intervals为虚线的ON和OFF数组,该数组的length必须大于等于2,phase为绘制时的偏移量。
我们先拿到对勾的path路径在对其改变偏移量加上DashPathEffect就能实现动态绘制对勾的效果了,那么怎么计算对勾的起点折点和终点的坐标呐,在网上找了一个不错的图片,如果你的设计师直接把位置给你标明的很详细的话你就省了这些自己计算的麻烦
private void initOk() { //对勾的路径 path.moveTo(default_two_circle_distance + height / 8 * 3, height / 2); path.lineTo(default_two_circle_distance + height / 2, height / 5 * 3); path.lineTo(default_two_circle_distance + height / 3 * 2, height / 5 * 2); pathMeasure = new PathMeasure(path, true); * 绘制对勾的动画 private void set_draw_ok_animation() { animator_draw_ok = ValueAnimator.ofFloat(1, 0); animator_draw_ok.setDuration(duration); animator_draw_ok.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { startDrawOk = true; float value = (Float) animation.getAnimatedValue(); effect = new DashPathEffect(new float[]{pathMeasure.getLength(), pathMeasure.getLength()}, value * pathMeasure.getLength()); okPaint.setPathEffect(effect); invalidate();再来看效果
至此动画分解都已完成,但是机智的你应该已经发现问题了,就是感觉动画播放衔接的不是很好,那么接下来我们就处理这个问题,回到最初的效果图上,矩形变圆角和缩放成圆形是同时进行的,那么我们有什么办法可以实现动画同时播放呐,哈哈,身为老司机的想必已经知道了使用AnimatorSet,他可以播放动画集、顺序播放等,那么我们就开始处理吧
我们让矩形变圆角和矩形往中间缩放同时进行,然后圆在上移,最后绘制对勾
animatorSet
.play(animator_move_to_up)
.before(animator_draw_ok)
.after(animator_rect_to_square)
.after(animator_rect_to_angle);
最终奉上我们自己一步一步完整实现的效果图