App开发中三种动画使用和属性详解

移动开发 Android
帧动画是顺序播放一组预先定义好的图片,不同于View动画,系统提供了另外一个类AnimationDrawable来使用帧动画.

[[437158]]

本文转载自微信公众号「Android开发编程」,作者Android开发编程。转载本文请联系Android开发编程公众号。

前言

这次我们介绍一下android中动画的分类:

View Animation(补间动画);

Drawable Animation(帧动画);

Property Animation(属性动画);

一、帧动画

帧动画是顺序播放一组预先定义好的图片,不同于View动画,系统提供了另外一个类AnimationDrawable来使用帧动画;

帧动画顾名思义就是通过顺序一帧一帧播放图片从而产生动画效果,效果类似放电影;

该动画缺点比较明显,就是如果图片过大过多会导致OOM。帧动画xml文件放置在drawable目录下而非anim文件夹下;

帧动画的使用

首先我们找一组帧动画的图片放入drawable-xhdpi文件夹下,其次在drawable文件夹下创建xml文件,如下所示:

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <animation-list 
  3.     xmlns:android="http://schemas.android.com/apk/res/android" 
  4.     android:oneshot="false"
  5.     <item android:drawable="@drawable/refresh1" android:duration="180"/> 
  6.     <item android:drawable="@drawable/refresh2" android:duration="180"/> 
  7.     ... 
  8.     <item android:drawable="@drawable/refresh25" android:duration="180"/> 
  9. </animation-list> 
  10. view = findViewById(R.id.test); 
  11.         view.setBackgroundResource(R.drawable.drawable_test_anim); 
  12.         view.setOnClickListener(new View.OnClickListener() { 
  13.             @Override 
  14.             public void onClick(View v) { 
  15.                 AnimationDrawable animationDrawable = (AnimationDrawable) view.getBackground(); 
  16.                 animationDrawable.start(); 
  17.             } 
  18.         }); 

属性介绍

  • <animation-list> 必须是根节点,包含一个或者多个<item>元素,属性有:
  • android:oneshot true代表只执行一次,false循环执行;
  • <item> 类似一帧的动画资源;
  • <item> animation-list的子项,包含属性如下:
  • android:drawable 一个frame的Drawable资源;
  • android:duration 一个frame显示多长时间;

二、补间动画

补间动画是通过对view进行旋转、缩放、渐变、透明度变化,而达到的一种动画效果;

是一种渐进式动画。并且可以通过组合以上四种操作,完成复杂的自定义动画效果;

缺点就是只是改变的view的展示状态,但是不会改变view的位置;

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <set xmlns:android="http://schemas.android.com/apk/res/android" 
  3.     android:duration="4000" 
  4.     android:fillAfter="true" 
  5.     android:fillBefore="true" 
  6.     android:interpolator="@[package:]anim/interpolator_resource" 
  7.     android:repeatMode="restart | reverse" 
  8.     android:repeatCount = “0” 
  9.     android:shareInterpolator="true" 
  10.     android:startOffset="float"
  11.     <alpha 
  12.         android:fromAlpha="float" 
  13.         android:toAlpha="float" /> 
  14.     <scale 
  15.         android:fromXScale="float" 
  16.         android:fromYScale="float" 
  17.         android:pivotX="float" 
  18.         android:pivotY="float" 
  19.         android:toXScale="float" 
  20.         android:toYScale="float" /> 
  21.     <rotate 
  22.         android:fromDegrees="float" 
  23.         android:pivotX="float" 
  24.         android:pivotY="float" 
  25.         android:toDegrees="float" /> 
  26.     <translate 
  27.         android:fromXDelta="float" 
  28.         android:fromYDelta="float" 
  29.         android:toXDelta="float" 
  30.         android:toYDelta="float" /> 
  31. </set

 

通用属性说明:

  • android:duration=""动画时长,单位毫秒
  • android:fillAfter="true"动画完成后是否停留在结束位置,默认false
  • android:fillBefore="true"动画完成后是否停留在起点位置。默认true,优先级低于fillAfter
  • android:interpolator为动画的变化速度【可以单独设置,可以直接放在set里面】
  • android:repeatMode="restart | reverse"动画重复策略 restart从起点位置(正序)重复,reverse从结束位置(倒序)重复
  • android:repeatCount = “0”重复次数 “infinite”为无线重复
  • android:shareInterpolator="true"动画集合中的动画是否公用一个差值器
  • android:startOffset="float"动画延迟时间

透明度动画

  • 透明度动画,通过改变view的透明度展示动画。对应AlphaAnimation和xml标签
  • android:fromAlpha="float" 起始透明度,取值范围(-1.0~1.0)
  • android:toAlpha="float"结束时透明度,取值范围(-1.0~1.0)

缩放动画

  • 缩放动画,通过修改view的大小展示动画。对应ScaleAnimation类和xml表情
  • android:fromXScale="float"动画在水平方向X的起始缩放倍数
  • android:fromYScale="float"动画在水平方向Y的结束缩放倍数
  • android:toXScale="float"动画在竖直方向X的结束缩放倍数
  • android:toYScale="float"动画在竖直方向Y的结束缩放倍数
  • android:pivotX="float"缩放中心点的x坐标
  • android:pivotY="float"缩放中心点的y坐标

旋转动画

  • 通过旋转view展示动画。对应RotateAnimation类和xml标签
  • android:fromDegrees="float"动画开始时 视图的旋转角度(正数 = 顺时针,负数 = 逆时针)
  • android:toDegrees="float"动画结束时 视图的旋转角度(正数 = 顺时针,负数 = 逆时针)
  • android:pivotX="float"旋转中心点的x坐标 具体如上缩放中心点参数解释
  • android:pivotY="float"旋转中心点的y坐标 具体如上缩放中心点参数解释

平移动画

  • 平移动画,更改view的展示位置展示动画。对应TranslateAnimation类和 xml表情
  • android:fromXDelta="float"view在水平x方向的起始值
  • android:fromYDelta="float"view在水平y方向的起始值
  • android:toXDelta="float"view在水平x方向的结束值
  • android:toYDelta="float" view在水平y方向的结束值

具体动画的使用

应用动画xml配置

  1. TextView textDemo = findViewById(R.id.text_demo); 
  2. Animation animation = AnimationUtils.loadAnimation(getApplicationContext(),R.anim.rotate_animation_test); 
  3. textDemo.startAnimation(animation); 

使用java类配置动画,具体参数类同xml参数,建议使用xml配置动画

  1. AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f, 2.0f); 
  2. textDemo.startAnimation(alphaAnimation); 

监听动画

  1. alphaAnimation.setAnimationListener(new Animation.AnimationListener() { 
  2.     @Override 
  3.     public void onAnimationStart(Animation animation) { 
  4.         //动画开始回调 
  5.     } 
  6.     @Override 
  7.     public void onAnimationEnd(Animation animation) { 
  8.         //动画结束回调 
  9.     } 
  10.     @Override 
  11.     public void onAnimationRepeat(Animation animation) { 
  12.         //动画重复时回调 
  13.     } 
  14. }); 

三、属性动画

属性动画本质是通过改变对象的属性(例如:x,y等属性),来实现动画的,所以基本上是无所不能的,只要对象有这个属性,就能实现动画效果;

属性动画是在api 11的新特性,通过动态的改变view的属性从而达到动画效果。虽然可以使用nineoldandroid库向下兼容,但是兼容本质是使用补间动画完成,也就是说不会更改view的属性,也不会更改view的位置;

属性动画比较常用的类:ValueAnimator、ObjectAnimator、AnimationSet,其中ObjectAnimator是ValueAnimator的子类,而AnminationSet是动画集合;

1.单个动画

  1. ObjectAnimator animator = ObjectAnimator 
  2.         .ofInt(textDemo, "backgroundColor", 0XffFF0000, 0Xff0000FF) 
  3.         .setDuration(2000); 
  4. animator.setRepeatMode(ValueAnimator.RESTART); 
  5. animator.setRepeatCount(10); 
  6. animator.start(); 

2.动画集合

  1. AnimatorSet animatorSet = new AnimatorSet(); 
  2. ValueAnimator translationX = ObjectAnimator.ofFloat(textDemo, "translationX", 200f); 
  3. ValueAnimator animator = ObjectAnimator 
  4.         .ofInt(textDemo, "backgroundColor", 0XffFF0000, 0Xff0000FF); 
  5. animatorSet.playTogether(translationX,animator); 
  6. animatorSet.setDuration(1000).start(); 

动画配置同样可以使用xml配置;

3.差值器和估值器

差值器(Interpolator)

根据时间流逝百分比计算当前属性改变百分比。同xml配置动画中的 android:interpolator属性配置,常见有LinearInterpolator(线性差值器)、AccelerateDecelerateInterpolator(加速减速差值器)等。自定义需要实现Interpolator或者TimeInterpolator。Interpolator接口继承TimeInterpolator;

  1. // Interpolator接口 
  2. public interface Interpolator extends TimeInterpolator{  
  3.     // 内部只有一个方法 
  4.      float getInterpolation(float input) {   
  5.          // 参数说明 
  6.          // input值值变化范围是0-1,且随着动画进度(0% - 100% )均匀变化 
  7.         // 即动画开始时,input值 = 0;动画结束时input = 1 
  8.         // 而中间的值则是随着动画的进度(0% - 100%)在0到1之间均匀增加 
  9.       ...// 插值器的计算逻辑 
  10.       return xxx; 
  11.       // 返回的值就是用于估值器继续计算的fraction值,下面会详细说明 
  12.     }   
  13. // TimeInterpolator接口 
  14. // 同上 
  15. public interface TimeInterpolator {   
  16.     float getInterpolation(float input);   

估值器(TypeEvaluator)

根据当前属性改变百分比计算改变后的属性值。属性动画特有的属性;自定义估值器需要实现TypeEvaluator接口;

  1. public interface TypeEvaluator {   
  2.     public Object evaluate(float fraction, Object startValue, Object endValue) {   
  3. // 参数说明 
  4. // fraction:插值器getInterpolation()的返回值 
  5. // startValue:动画的初始值 
  6. // endValue:动画的结束值 
  7.         ....// 估值器的计算逻辑 
  8.         return xxx; 
  9.         // 赋给动画属性的具体数值 
  10.         // 使用反射机制改变属性变化 

可以对任意属性做属性动画,属性动画要求动画作用的对象提供该属性的get()和set()方法。因为属性动画本质就是根据外界传递的对象属性的初始值和终点值,然后根据估值器和差值器计算属性值,不断调用属性的set方法,通过时间的推移所传递的值,越来越近终点值;

注意:

对象属性必须提供对应的set方法,而且如果没有初始值传入的情况下必须要设置get方法,因为 系统要获取初始值,如果没有满足条件则程序cash;

对象属性的set方法对属性做出改变,需要能够通过某种方法表示出来。带来ui展示效果的改变。否则动画不会生效;

ValueAnimator

使用ValueAnimator通过监听动画过程,自己改变对象属性完成动画

  1. ValueAnimator valueAnimator = ValueAnimator.ofInt(1, 100); 
  2.         valueAnimator.setDuration(2000);//动画持续时间 
  3.         valueAnimator.setRepeatCount(0);//重复次数 
  4.         valueAnimator.setRepeatMode(ValueAnimator.REVERSE);//重复方式, 
  5.         valueAnimator.setStartDelay(20);//开始前延迟时间 
  6.         valueAnimator.setEvaluator(new IntEvaluator());//估值器 
  7.         valueAnimator.setInterpolator(new LinearInterpolator());//差值器 
  8.         valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 
  9.             @Override 
  10.             public void onAnimationUpdate(ValueAnimator animation) { 
  11.                 //获取当前动画属性值,即1~100 
  12.                 Integer animatedValue = (Integer) animation.getAnimatedValue(); 
  13.                 //获取动画的百分比 
  14.                 float animatedFraction = animation.getAnimatedFraction(); 
  15.                 ViewGroup.LayoutParams layoutParams = textView.getLayoutParams(); 
  16.                 int width = layoutParams.width; 
  17.                 int height = layoutParams.height; 
  18.                 layoutParams.height = height + 1; 
  19.                 layoutParams.width=width+1; 
  20.                 Log.e(TAG,"animatedValue: "+animatedValue+" animatedFraction : "+animatedFraction 
  21.                 +" width : "+layoutParams.width+" height : "+layoutParams.height); 
  22.                 textView.requestLayout(); 
  23.             } 
  24.         }); 
  25.         valueAnimator.start(); 
  26.     } 

四、注意事项

OOM注意,在帧动画中如果图片过大、数量过多容易出现;

内存泄漏, 切记在activity销毁时,停止动画。否则一些无限循环动画将导致activity不能释放而内存泄漏。出现在属性动画中,view动画不存在此类问题;

View动画即补间动画,是改变view的视觉位置,改变view的影像展示位置,而不改变真实位置;注意交互体验。可能会出现view动画结束后,view无法隐藏的问题及setVisibility(View.GONE)失效。此时调用view.clearAnimation()清除动画。可修复此类问题;

总结

公众号里面是系统的总结,但是要系统学习一类的知识点了,又不是很好;

 

于是就想写个小册-掘金小册,这样老铁们就可以系统的学习某个知识点了;

 

责任编辑:武晓燕 来源: Android开发编程
相关推荐

2011-08-01 18:42:40

分区维度物化视图

2024-07-16 14:15:09

2018-01-17 15:02:28

VMware网络连接

2012-03-26 12:23:25

JavaSwing

2017-01-05 16:19:12

C++正则表达式

2024-02-26 13:47:00

C#Socket数据接收

2009-06-09 16:53:22

Java Swing处理方法比较

2009-07-01 17:22:05

连接字符串

2024-04-11 12:57:55

Python函数

2021-03-17 09:59:26

Python函数调用

2021-07-10 10:01:37

Python简单函数

2010-04-02 13:15:01

Oracle跟踪

2009-12-01 09:18:22

Linux版本

2021-11-23 10:30:35

Android技术代码

2013-06-17 17:08:47

Windows PhoWP开发共享数据方式

2024-04-25 12:49:22

2010-04-26 12:19:28

Oracle 数据库

2022-06-20 08:50:16

TypeScript类型语法

2013-12-18 15:45:33

多核

2023-10-28 16:25:17

滤波C++
点赞
收藏

51CTO技术栈公众号