前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android开发中基础动画技巧的应用 原

Android开发中基础动画技巧的应用 原

作者头像
珲少
发布2018-08-15 16:03:48
7340
发布2018-08-15 16:03:48
举报
文章被收录于专栏:一“技”之长一“技”之长

Android开发中基础动画技巧的应用

一、引言

        我是先入门iOS的移动开发者,提到动画开发,iOS开发者很容易联想到3种方式,UIImageView的帧动画,UIView层的属性动画和CoreAnimation动画。Android中也有3种方式创建基础动画效果,分别为View Animation,Property Animation和Drawable Animation。由于Android开发的固有特点,其在进行动画编程时也支持使用代码和xml配置文件两种方式。本篇博客,将主要向大家介绍这3种创建Android动画方式的使用方法与可以做到的效果。

二、View Animation动画的应用

        View Animation又被称为Tweened Animation,其应用于View视图变化的动画过渡效果。View Animation主要分为如下4类:

①.AlphaAnimation:透明度动画

②.RotateAnimation:旋转动画

③.ScaleAnimation:缩放动画

④.TranslateAnimation:位移动画

1.AlphaAnimation的应用

    AlphaAnimation用于当视图透明度发生变化时展示过渡动画,可以渐隐也可以渐现。使用AlphaAnimation创建动画的核心代码如下:

代码语言:javascript
复制
//创建AlphaAnimation动画对象 构造方法中需要传入两个float值 分别是视图动画起始的alpha值与最终的alpha值
AlphaAnimation alphaAnimation = new AlphaAnimation(1,0);
//设置动画执行时间 
alphaAnimation.setDuration(3000);
//调用视图的startAnimation方法来开启动画
animationImageView.startAnimation(alphaAnimation);
2.RotateAnimation的应用

    RotateAnimation用于创建视图的旋转动画。其相比AlphaAnimation要复杂一些,在使用时,除了需要设置其动画的起始角度和最终角度外,还可以设置视图旋转时的参照位置,示例代码如下:

代码语言:javascript
复制
//创建旋转动画对象
RotateAnimation rotateAnimation = new RotateAnimation(0,360, Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
//设置动画时间
rotateAnimation.setDuration(3000);
//开始动画
animationImageView.startAnimation(rotateAnimation);

这里使用了RotateAnimation类中最复杂的一个构造方法,其中需要传入6个参数,前两个参数分别为旋转动画的起始角度与终止角度,第3个参数为旋转参照点的x轴相对位置类型,第4个参数为参照点x轴位置,第5个和第6个参数分别为旋转参照点的y轴相对位置类型与y轴相对位置。

    关于参照点的相对位置类型,Animation类中定义了几个常量供开发者选择使用,意义如下:

代码语言:javascript
复制
//绝对定位 以当前窗口做参照
public static final int ABSOLUTE = 0;
//以其父视图做为位置参照
public static final int RELATIVE_TO_PARENT = 2;
//以本身作为位置参照
public static final int RELATIVE_TO_SELF = 1;

还有一点需要注意,如果选择的参照类型是RELATIVE_TO_SELF,则参照点的位置参数取值范围为0-1之间,代表的是相对于自身的位置比例,如果参照类型是RELATIVE_TO_PARENT,则参照点的位置参数取值范围为0-1之间,代表的是相对于父视图的位置比例,如果参照类型是ABSOLUTE,则参照点的位置参数取值为绝对坐标值,例如100,150,其代表了相对窗口视图的坐标位置。例如上面示例代码中,以视图本身为参照物,x、y轴位置都设置为0.5,则旋转动画以视图本身中心为旋转点,如果需要以视图右下角为旋转点,修改代码如下:

代码语言:javascript
复制
RotateAnimation rotateAnimation = new RotateAnimation(0,360, Animation.RELATIVE_TO_SELF,1f,Animation.RELATIVE_TO_SELF,1f);
3.ScaleAnimation的应用

        ScaleAnimation用于创建放大或者缩小的形变动画,示例代码如下:

代码语言:javascript
复制
//创建缩放动画对象
ScaleAnimation scaleAnimation = new ScaleAnimation(1,2,1,2,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
//设置动画时间
scaleAnimation.setDuration(3000);
//执行动画
animationImageView.startAnimation(scaleAnimation);

上面示例代码中前4个参数分别设置缩放动画x轴方向的起始值、最终值和y轴方向的起始值、终止值。需要注意,这里的单位都是比例,1表示原视图尺寸,2表示原视图尺寸的2倍。这个方法后4个参数的意义是确定缩放参照点的位置,和RotateAniamtion构造方法中的参数意义一致。

4.TranslateAnimation的应用

        TranslateAnimation用于创建位移动画,示例代码如下:

代码语言:javascript
复制
//创建位移动画对象
TranslateAnimation translateAnimation = new TranslateAnimation(Animation.ABSOLUTE,0,Animation.ABSOLUTE,100,Animation.RELATIVE_TO_SELF,0,Animation.RELATIVE_TO_SELF,1);
//设置动画时间
translateAnimation.setDuration(3000);
//执行动画
animationImageView.startAnimation(translateAnimation);

上面示例代码中使用的TranslateAnimation构造方法中的8个参数分别代表,起始位置的x轴参照点类型与起始位置的x轴值、终止位置的x轴参照点类型与终止位置的x轴值、起始位置的y轴参照点类型与起始位置的y轴值、终止位置的y轴参照点类型与终止位置的y轴值。

5.Animation类中的通用方法

        上面介绍的4种动画实际上都是Animation类的子类,Animation类中封装了许多动画通用的方法,例如前面使用的设置动画执行时间的方法setDuration就是Animation类的方法,其中更多常用方法列举如下:

代码语言:javascript
复制
//取消正在执行的动画
public void cancel();
//设置动画的执行函数
public void setInterpolator(Interpolator i);
//这只方法设置开始动画的延时值 单位为毫秒
public void setStartOffset(long startOffset);
//设置动画的执行时间
public void setDuration(long durationMillis);
//设置动画特效的最长运行时间
public void restrictDuration(long durationMillis);
//设置动画的执行强度比例 例如放大两倍的动画 这个值如果设置为2 将被放大4倍
public void scaleCurrentDuration(float scale);
//为动画设置一个开始的时间
public void setStartTime(long startTimeMillis);
//设置动画循环模式
/*
只有当动画的循环次数大于1时这个值才有效果,其可以设置为如下常量:
RESTART 每次循环都从头执行
REVERSE 正逆交替执行
*/
public void setRepeatMode(int repeatMode);
//设置循环次数 设置为INFINITE则为无限循环
public void setRepeatCount(int repeatCount);
//设置是否允许填充动画 这个方法设置为true后setFillBefore()与setFillAfter()方法才会生效
public void setFillEnabled(boolean fillEnabled);
//动画结束后 是否以起始位置填充视图
public void setFillBefore(boolean fillBefore);
//动画结束后 是否以结束位置填充视图
public void setFillAfter(boolean fillAfter)
//设置动画执行时在Z轴上的位置
/*
可以设置为如下3中常量
    public static final int ZORDER_BOTTOM = -1; //将动画放在Z轴最下边
    public static final int ZORDER_NORMAL = 0;  //将动画放在Z轴原位置
    public static final int ZORDER_TOP = 1;     //将动画放在Z轴最上边
*/
public void setZAdjustment(int zAdjustment);
//设置动画的执行是否影响到壁纸
public void setDetachWallpaper(boolean detachWallpaper);
//获取动画是否开始执行了
public boolean hasStarted();
//获取动画是否结束执行了
public boolean hasEnded();

上面列举的方法中,setInterpolator()方法很有意思,其可以设置动画执行的时间函数,例如是先快后慢还是先慢后快等等,这个方法需要传入一个Interpolator类型的参数,实际上使用时是通过Interpolator的子类来实现的,示例如下:

代码语言:javascript
复制
ranslateAnimation.setInterpolator(new AccelerateDecelerateInterpolator());

对于Interpolator参数开发者可以设置的子类及意义列举如下:

AccelerateDecelerateInterpolator:先加速后减速执行

AccelerateInterpolator:加速执行

AnticipateInterpolator:先后退执行一步后正向加速执行(类似弹簧效果)

 AnticipateOvershootInterpolator:先后退执行一步后加速执行到达极限后再前进一步后再回到极限(弹簧)

BounceInterpolator:动画执行到结尾后进行阻尼效果

CycleInterpolator:以正弦规则循环执行数次动画,这个类来构造时需要传入循环次数,如下:

代码语言:javascript
复制
new CycleInterpolator(3)

DecelerateInterpolator:减速执行动画

 FastOutLinearInInterpolator:基于贝塞尔曲线的速率变化

 FastOutSlowInInterpolator:基于贝塞尔曲线的速率变化

 LinearInterpolator:线性匀速执行

LinearOutSlowInInterpolator:基于贝塞尔曲线的速率变化

OvershootInterpolator:执行超出极限后在回退

PathInterpolator:自定义运动路径

6.实现对Animation动画状态的监听

        Animation类中也定义了一个监听器协议,其中提供了对动画状态进行监听的方法,如下:

代码语言:javascript
复制
public interface AnimationListener {
    //当动画开始执行时触发的方法
    void onAnimationStart(Animation var1);
    //动画执行结束后触发的方法
    void onAnimationEnd(Animation var1);
    //动画重复执行的时候会触发
    void onAnimationRepeat(Animation var1);
}
7.使用xml文件配置View Animation

        上面介绍的全部是通过代码来创建View Animation动画,Android也支持使用xml文件来配置View Animation动画。

首先在Android Studio的res目录中创建一个动画文件目录,将其类型选择为anim,如下图所示:

在创建的目录中创建一个新的xml文件,在其中编写动画代码如下:

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <alpha android:fromAlpha="1" android:toAlpha="0" android:duration = "3000"/>
</set>

在代码中,使用如下代码来加载xml配置的动画:

代码语言:javascript
复制
//加载动画文件
Animation animation = AnimationUtils.loadAnimation(this,R.anim.my_anmi);
//执行动画
animationImageView.startAnimation(animation);
8.复合的View Animation

        View Animation也支持进行复合动画的操作,如果使用xml配置复合动画,十分简单,只需要将要要复合的动画都配置进xml文件的set标签中即可,如下:

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <alpha android:fromAlpha="1" android:toAlpha="0" android:duration = "3000"/>
    <scale android:fromXScale="1" android:toXScale="2" android:fromYScale="1" android:toYScale="2" android:duration="3000"/>
</set>

如果要用代码创建复合动画,需要使用到AnimationSet类进行复合,示例如下:

代码语言:javascript
复制
//创建动画集合容器 参数决定容器中所有动画是否共用Interpolator时序函数
AnimationSet set = new AnimationSet(true);
//创建动画
RotateAnimation rotateAnimation = new RotateAnimation(0,360, Animation.RELATIVE_TO_SELF,1f,Animation.RELATIVE_TO_SELF,1f);
ScaleAnimation scaleAnimation = new ScaleAnimation(1,2,1,2,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
scaleAnimation.setDuration(3000);
rotateAnimation.setDuration(3000);
//将动画添加进集合中
set.addAnimation(rotateAnimation);
set.addAnimation(scaleAnimation);
//执行动画
animationImageView.startAnimation(set);

三、Property Animation动画的应用

        在前面介绍的View Animation动画体系中,虽然使用起来十分方便,但也有十分多的局限性,例如只能支持透明度,位置,缩放和旋转动画,并且在动画执行时,视图实际上并没有移动,如果需要做动画的是可以用户交互的按钮控件则会带来很多的不便。在Android3.0之后,系统推出了Property Animation动画,这种机制可以将对象任意属性的修改实现过渡动画效果。

1.ObjectAnimator动画的应用

        ObjectAnimator是Property Animation动画体系中最简单易用的一种方式,开发者只需要设置要改变的属性值和一些动画参数即可使用,例如若要实现视图以y方向为轴进行旋转操作,使用 如下代码实现:

代码语言:javascript
复制
//创建属性动画对象
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(animationImageView,"rotationY",0,360,0);
//设置动画时间
objectAnimator.setDuration(3000);
//开始动画
objectAnimator.start();

ObjectAnimator类的静态方法ofFloat()用于创建属性动画实例本身,与其类似的方法还有ofInt()与ofObject()。需要注意,这些方法第1个参数为要执行动画的视图,第2个参数为要发生动画改变的属性名,从第3个参数开始后面可以添加任意多个值,这些值代表了属性值改变的路径,例如上面示例代码表示将视图以y方向为轴从0°开始旋转到360°后再旋转回0°。

    ObjectAnimator类继承自ValueAnimator,ValueAnimator类则更加灵活自由,其可以为自定义类的自定义属性做动画处理,后面会介绍,ValueAnimator类中提供了许多动画配置的方法,常用如下:

代码语言:javascript
复制
//设置动画执行时间
public ValueAnimator setDuration(long duration);
//设置延时执行
public void setStartDelay(long startDelay);
//设置动画循环次数
public void setRepeatCount(int value);
//设置动画循环模式
public void setRepeatMode(int value);
//设置动画执行时序模式
public void setInterpolator(TimeInterpolator value);
//开始执行动画
public void start();
//结束动画
public void end();
//取消动画
public void cancel();
//恢复动画
public void resume();
//暂停动画
public void pause();

需要注意,使用ObjectAnimator创建动画的属性必须实现set和get方法。

2.ValueAnimator实现更加灵活的自定义动画

        ObjectAnimator是ValueAnimator的子类,可以理解,ValueAnimator要比ObjectAnimator更加灵活自由,其可以实现任意自定义属性的动画行为。示例代码如下:

代码语言:javascript
复制
//创建ValueAnimator实例
ValueAnimator valueAnimator = new ValueAnimator();
//设置动画的路径值
valueAnimator.setFloatValues(0,200,100,300,0);
//设置动画的执行时间
valueAnimator.setDuration(6000);
//添加动画执行监听
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
   //这个方法会在每次动画值改变时调用
   @Override
   public void onAnimationUpdate(ValueAnimator valueAnimator) {
       //设置视图的横坐标 
       animationImageView.setX((Float) valueAnimator.getAnimatedValue());
   }
});
//执行动画
valueAnimator.start();

如果运行上面代码,可以看到视图在6s内从x坐标点为0的地方平移到200后再次回到100后再次移动到300最终回到原点0。

       上面的示例代码只是演示了ValueAnimator的工作原理,开发者可以在onAnimationUpdate()方法中进行任意属性的修改。仅从上面演示代码并不能体现出ValueAnimator的强大之处,可以通过实现类似抛物线的动画来理解ValueAnimator的灵活之处,示例代码如下:

代码语言:javascript
复制
//创建ValueAnimator实例
final ValueAnimator animator = new ValueAnimator();
//示例进行抛物线动画 让控件从(0,0)点位置移动到x轴为400的位置,y轴方向做自由落体
animator.setObjectValues(new Point(0,0),new Point(400,0));
//设置动画时间
animator.setDuration(4000);
//设置时序为线性函数
animator.setInterpolator(new LinearInterpolator());
//由于抛物线运动在x轴和y轴上的速度变化并不相同 需要自定义枚举器
animator.setEvaluator(new TypeEvaluator<Point>() {
   //这个枚举方法中传入的v值为动画执行的比例 0为初始状态 1为动画执行完成 开发者根据这个值模拟抛物线坐标
   @Override
   public Point evaluate(float v, Point o,Point t1) {
       //创建Point对象 模拟抛物运动
       Point point = new Point();
       point.x = (int)((v*8)*100);
       point.y = (int)((v*60)*(v*60)/4); 
       return point;
   }
});
//监听动画执行
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator valueAnimator) {
        //设置视图位置
        animationImageView.setX(((Point)valueAnimator.getAnimatedValue()).x);
        animationImageView.setY(((Point)valueAnimator.getAnimatedValue()).y);
   }
});
//执行动画
animator.start();

需要注意,Property Animation与View Animation最大的不同在于View Animation只是展示视图的界面动画,它并没有真正改变视图的属性,而Property Animation是实实在在的改变了发生动画控件的属性。

3.Property Animation动画的监听

        ValueAnimator对象可以使用addListener()方法来添加监听者,接口方法如下:

代码语言:javascript
复制
//动画监听接口
public interface AnimatorListener {
    //动画开始
    void onAnimationStart(Animator var1);
    //动画结束
    void onAnimationEnd(Animator var1);
    //动画取消
    void onAnimationCancel(Animator var1);
    //动画重复
    void onAnimationRepeat(Animator var1);
}
4.使用PropertyValuesHolder进行动画复合

        对于Property Animation,开发者可以通过ValueAnimator实现自定义的复合动画,也可以使用PropertyValuesHolder进行属性动画的复合操作,示例如下:

代码语言:javascript
复制
//创建子属性动画  翻转
PropertyValuesHolder holder = PropertyValuesHolder.ofFloat("rotationY",0,360,90);
//创建子属性动画  透明
PropertyValuesHolder holder2 = PropertyValuesHolder.ofFloat("alpha",1,0,1);
//进行动画复合
ObjectAnimator objectAnimation = ObjectAnimator.ofPropertyValuesHolder(animationImageView,holder,holder2);
//执行动画
objectAnimation.setDuration(3000);
objectAnimation.start();

三、Drawable Animation动画的应用

        相比前两种动画模式,Drawable Animation动画要容易的多,其使用一组图像快速切换的原理来实现动画效果。

在Android Studio的drawable文件夹中添加一个animation文件,xml代码如下:

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/bird1" android:duration="200" />
    <item android:drawable="@drawable/bird2" android:duration="200" />
    <item android:drawable="@drawable/bird3" android:duration="200" />
    <item android:drawable="@drawable/bird4" android:duration="200" />
    <item android:drawable="@drawable/bird5" android:duration="200" />
    <item android:drawable="@drawable/bird6" android:duration="200" />
    <item android:drawable="@drawable/bird7" android:duration="200" />
    <item android:drawable="@drawable/bird8" android:duration="200" />
</animation-list>

将需要展示动画的视图背景设置为这个drawable文件,示例如下:

代码语言:javascript
复制
 <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/anmi_draw_list"
        android:id="@+id/animatedImageView"/>

在需要开始动画时,调用如下代码即可:

代码语言:javascript
复制
//获取到drawable背景 调用start()方法开始动画
((AnimationDrawable)animationImageView.getBackground()).start();

专注技术,热爱生活,交流技术,也做朋友。 ——珲少

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016/08/17 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Android开发中基础动画技巧的应用
    • 一、引言
      • 二、View Animation动画的应用
        • 1.AlphaAnimation的应用
        • 2.RotateAnimation的应用
        • 3.ScaleAnimation的应用
        • 4.TranslateAnimation的应用
        • 5.Animation类中的通用方法
        • 6.实现对Animation动画状态的监听
        • 7.使用xml文件配置View Animation
        • 8.复合的View Animation
      • 三、Property Animation动画的应用
        • 1.ObjectAnimator动画的应用
        • 2.ValueAnimator实现更加灵活的自定义动画
        • 3.Property Animation动画的监听
        • 4.使用PropertyValuesHolder进行动画复合
      • 三、Drawable Animation动画的应用
      相关产品与服务
      容器服务
      腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档