十分钟搞定酷炫动画,Android自定义 View 入门

前几天 Ui 突然给我一个 gif 图说要把这个做成启动动画,看到效果图的我表示一脸懵逼。

好吧,懵逼归懵逼,效果还是要做出来,作为一只没怎么写过动效的猿,第一反应就是让 Ui 做成 gif 图,然后 Ios 的哥们说 gif 图内存大,容易失真,我们都已经用贝塞尔曲线做出来了(Ios 比我们 android 先跑半个版本)。好吧,那就手撸动效吧,宝宝不哭。

首先对着 gif 图一帧一帧观察了一遍,分析动画的过程。把动画拆解成两部分:

  1. 四个颜色的圆运动。
  2. Logo的出现

logo 的出现就是简单的alpha 动画,难点就在四个圆运动。 找 Ui 拿到了四个圆的运动轨迹,如下图所示:

根据轨迹,我把运动轨迹拆分成平移和半圆旋转,创建出Path路径,再让圆沿着 Path 运动,在运动的时候加上 alpha 和缩放的属性,结束的时候把圆移除掉并显示 logo 就好。

分析结束,接下来就上代码: 第一步:创建 LauncherView 继承 RelativeLayout,在构造方法里面 init()添加四个颜色的圆

private void init(){

LayoutParamslp=newLayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);

lp.addRule(CENTER_HORIZONTAL,TRUE);//这里的TRUE 要注意 不是true

lp.addRule(CENTER_VERTICAL,TRUE);

lp.setMargins(0,0,0,dp80);

purple=newImageView(getContext());

purple.setLayoutParams(lp);

purple.setImageDrawable(getResources().getDrawable(R.drawable.shape_circle_purple));

addView(purple);

yellow=newImageView(getContext());

yellow.setLayoutParams(lp);

yellow.setImageDrawable(getResources().getDrawable(R.drawable.shape_circle_yellow));

addView(yellow);

blue=newImageView(getContext());

blue.setLayoutParams(lp);

blue.setImageDrawable(getResources().getDrawable(R.drawable.shape_circle_blue));

addView(blue);

red=newImageView(getContext());

red.setLayoutParams(lp);

red.setImageDrawable(getResources().getDrawable(R.drawable.shape_circle_red));

addView(red);

}

ObjectAnimator动画原理

ObjectAnimator.ofObject(….,”xxx”,估值值,区间数组); 【定义动画属性xxx和区间】

插值器/加速器(Interpolator)【返回当前数字进度t】

估值值(Evaluator)【根当前数字进度计算并返回当前值】

调用setXxx函数 【根据封装好的setXxx函数并反射调用,将第三步返回当前值以参数传入】

自定义ObjectAnimator属性请戳这里:http://blog.csdn.net/cxmscb/article/details/52485878

绘制四个圆圈的 Path,这里以红色圆圈为例,三阶贝塞尔曲线描点不会的话,可以参考 Ui 的设计路径描点,Ps 的钢笔工具就是贝塞尔曲线。

ViewPathredPath1=newViewPath();//偏移坐标

redPath1.moveTo(0,0);

redPath1.lineTo(mWidth/5-mWidth/2,0);

ViewPathredPath2=newViewPath();

redPath2.moveTo(mWidth/5-mWidth/2,0);

redPath2.curveTo(-700,-mHeight/2,mWidth/3*2,-mHeight/3*2,0,-dp80);

setAnimation(red,redPath1,redPath2);

接下来将 Path 转换成 ObjectAnimation

private void setAnimation(final ImageView target,ViewPath path1,ViewPath path2){

//左右平移

ObjectAnimator redAnim1=ObjectAnimator.ofObject(newViewObj(target),"fabLoc",newViewPathEvaluator(),path1.getPoints().toArray());

redAnim1.setInterpolator(newAccelerateDecelerateInterpolator());

redAnim1.setDuration(800);

//贝塞尔曲线

ObjectAnimator redAnim2=ObjectAnimator.ofObject(newViewObj(target),"fabLoc",newViewPathEvaluator(),path2.getPoints().toArray());

redAnim2.setInterpolator(newAccelerateDecelerateInterpolator());

//组合动画

addAnimation(redAnim1,redAnim2,target);

}

然后组合动画得到一个圆的完整运行轨迹。

private void addAnimation(ObjectAnimatoranimator1,ObjectAnimatoranimator2,ImageViewtarget){

ObjectAnimator alpha=ObjectAnimator.ofFloat(target,View.ALPHA,1f,0.5f);

ObjectAnimator scaleX=ObjectAnimator.ofFloat(target,View.SCALE_X,1,getScale(target),1.0f);

ObjectAnimator scaleY=ObjectAnimator.ofFloat(target,View.SCALE_Y,1,getScale(target),1.0f);

AnimatorSet all2=newAnimatorSet();

all2.setDuration(1800);

all2.playTogether(alpha,scaleX,scaleY,animator2);

all2.addListener(newAnimEndListener(target));

AnimatorSetall=newAnimatorSet();

all.playSequentially(animator1,all2);

all.start();

}

最后,显示 logo 动画

private void showLogo(){

Viewview=View.inflate(getContext(),R.layout.widget_load_view,this);

Viewlogo=view.findViewById(R.id.iv_logo);

finalViewslogo=view.findViewById(R.id.iv_slogo);

ObjectAnimatoralpha=ObjectAnimator.ofFloat(logo,View.ALPHA,0f,1f);

alpha.setDuration(800);

alpha.start();

newHandler().postDelayed(newRunnable(){

@Override

public voidrun(){

ObjectAnimator alpha=ObjectAnimator.ofFloat(slogo,View.ALPHA,0f,1f);

alpha.setDuration(200);

alpha.start();

}

},400);

}

好,到这里,炫酷的启动页动画已经撸出来了,就是一个简单的ObjectAnimator使用,大家不要被自定义 view 这个纸老虎吓到。

项目源码地址:https://github.com/diamondlin2016/LauncherView

原文发布于微信公众号 - 非著名程序员(non-famous-coder)

原文发表时间:2016-11-02

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏移动开发的那些事儿

Android界面绘制原理

从普遍的意义上来讲,以上这段代码就是设置WindowManager和DecorView的关系,继续看:

1571
来自专栏移动开发

利用 CollapsingToolbarLayout 完成联动的动画效果

最初的想法是自己去利用 Android 的嵌套滚动机制,去实现上面的嵌套滚动效果.但最后为了开发效率直接利用了 CollapsingToolbarLayout...

1231
来自专栏Winter漫聊技术

Android水波动画帮助类,一行代码实现View显示/隐藏/startActivity特效(0.3.1)

So,你可以如下compile该library了,也可以把这个类CircularAnim拷贝到项目里去。

1022
来自专栏Android学习之路

ViewDragHelper使用笔记及侧滑菜单实践

3406
来自专栏向治洪

android属性动画

1、概述 Android提供了几种动画类型:View Animation 、Drawable Animation 、Property Animation 。V...

1875
来自专栏非著名程序员

Android中如何动态的实现设置全屏和退出全屏

在我们的开发过程中,实现Activity全屏的效果经常遇见,当然我相信大家都肯定使用过,估计也会用,但是推出全屏的方法估计大家应该大多数人没有用过。在这里我就给...

2465
来自专栏Android点滴积累

Android XML shape 标签使用详解(apk瘦身,减少内存好帮手)

  一个android开发者肯定懂得使用 xml 定义一个 Drawable,比如定义一个 rect 或者 circle 作为一个 View 的背景。但是,也肯...

1210
来自专栏开发之途

Android 仿360悬浮球与加速球

4528
来自专栏Android干货

Android项目实战(四):ViewPager切换动画(3.0版本以上有效果)

3695
来自专栏Android开发指南

11.粘性控件

3696

扫码关注云+社区

领取腾讯云代金券