参考文章:Android 三种动画详解

一、view animation 视图动画(补间动画)

只能被用来设置View的动画。

可以使用xml或者java 代码进行实现

xml放在 res/anim/ 下

android:duration 动画持续时间,以毫秒为单位 android:fillAfter 如果设置为true,控件动画结束时,将保持动画最后时的状态 android:fillBefore 如果设置为true,控件动画结束时,还原到开始动画前的状态 android:fillEnabled 与android:fillBefore 效果相同,都是在动画结束时,将控件还原到初始化状态 android:repeatCount 重复次数 android:repeatMode 重复类型,有reverse和restart两个值,reverse表示倒序回放,restart表示重新放一遍,必须与repeatCount一起使用才能看到效果。因为这里的意义是重复的类型,即回放时的动作。 android:interpolator 设定插值器,其实就是指定的动作效果,比如弹跳效果等,

java类名xml关键字描述信息
AlphaAnimation<alpha> 放置在res/anim/目录下渐变透明度动画效果
RotateAnimation<rotate> 放置在res/anim/目录下画面转移旋转动画效果
ScaleAnimation<scale> 放置在res/anim/目录下渐变尺寸伸缩动画效果
TranslateAnimation<translate>放置在res/anim/目录下画面转换位置移动动画效果
AnimationSet<set> 放置在res/anim/目录下一个持有其它动画元素alpha、scale、translate、rotate或者其它set元素的容器

xml属性java方法解释
android:detachWallpapersetDetachWallpaper(boolean)是否在壁纸上运行
android:durationsetDuration(long)动画持续时间,毫秒为单位
android:fillAftersetFillAfter(boolean)控件动画结束时是否保持动画最后的状态
android:fillBeforesetFillBefore(boolean)控件动画结束时是否还原到开始动画前的状态
android:fillEnabledsetFillEnabled(boolean)与android:fillBefore效果相同
android:interpolatorsetInterpolator(Interpolator)设定插值器(指定的动画效果,譬如回弹等)
android:repeatCountsetRepeatCount(int)重复次数
android:repeatModesetRepeatMode(int)重复类型有两个值,reverse表示倒序回放,restart表示从头播放
android:startOffsetsetStartOffset(long)调用start函数之后等待开始运行的时间,单位为毫秒
android:zAdjustmentsetZAdjustment(int)表示被设置动画的内容运行时在Z轴上的位置(top/bottom/normal),默认为normal

1、Alpha属性详解 透明度

xml属性java方法解释
android:fromAlphaAlphaAnimation(float fromAlpha, …)动画开始的透明度(0.0到1.0,0.0是全透明,1.0是不透明)
android:toAlphaAlphaAnimation(…, float toAlpha)动画结束的透明度,同上

2、Rotate属性详解 旋转

xml属性java方法解释
android:fromDegreesRotateAnimation(float fromDegrees, …)旋转开始角度,正代表顺时针度数,负代表逆时针度数
android:toDegreesRotateAnimation(…, float toDegrees, …)旋转结束角度,正代表顺时针度数,负代表逆时针度数
android:pivotXRotateAnimation(…, float pivotX, …)缩放起点X坐标(数值、百分数、百分数p,譬如50表示以当前View左上角坐标加50px为初始点、50%表示以当前View的左上角加上当前View宽高的50%做为初始点、50%p表示以当前View的左上角加上父控件宽高的50%做为初始点)
android:pivotYRotateAnimation(…, float pivotY)缩放起点Y坐标,同上规律

3、Scale属性详解 缩放

xml属性java方法解释
android:fromXScaleScaleAnimation(float fromX, …)初始X轴缩放比例,1.0表示无变化
android:toXScaleScaleAnimation(…, float toX, …)结束X轴缩放比例
android:fromYScaleScaleAnimation(…, float fromY, …)初始Y轴缩放比例
android:toYScaleScaleAnimation(…, float toY, …)结束Y轴缩放比例
android:pivotXScaleAnimation(…, float pivotX, …)缩放起点X轴坐标(数值、百分数、百分数p,譬如50表示以当前View左上角坐标加50px为初始点、50%表示以当前View的左上角加上当前View宽高的50%做为初始点、50%p表示以当前View的左上角加上父控件宽高的50%做为初始点)
android:pivotYScaleAnimation(…, float pivotY)缩放起点Y轴坐标,同上规律

4、Translate属性详解 移动

xml属性java方法解释
android:fromXDeltaTranslateAnimation(float fromXDelta, …)起始点X轴坐标(数值、百分数、百分数p,譬如50表示以当前View左上角坐标加50px为初始点、50%表示以当前View的左上角加上当前View宽高的50%做为初始点、50%p表示以当前View的左上角加上父控件宽高的50%做为初始点)
android:fromYDeltaTranslateAnimation(…, float fromYDelta, …)起始点Y轴从标,同上规律
android:toXDeltaTranslateAnimation(…, float toXDelta, …)结束点X轴坐标,同上规律
android:toYDeltaTranslateAnimation(…, float toYDelta)结束点Y轴坐标,同上规律

5、使用

Animation animation = AnimationUtils.loadAnimation(this, R.anim.alphaanim);
btn.setAnimation(animation);

6、插值器Interpolator介绍

各种插值器都是实现了Interpolator接口,系统提供了许多已经实现好的插值器,具体如下:

java类xml id值描述
AccelerateDecelerateInterpolator@android:anim/accelerate_decelerate_interpolator动画始末速率较慢,中间加速
AccelerateInterpolator@android:anim/accelerate_interpolator动画开始速率较慢,之后慢慢加速
AnticipateInterpolator@android:anim/anticipate_interpolator开始的时候从后向前甩
AnticipateOvershootInterpolator@android:anim/anticipate_overshoot_interpolator类似上面AnticipateInterpolator
BounceInterpolator@android:anim/bounce_interpolator动画结束时弹起
CycleInterpolator@android:anim/cycle_interpolator循环播放速率改变为正弦曲线
DecelerateInterpolator@android:anim/decelerate_interpolator动画开始快然后慢
LinearInterpolator@android:anim/linear_interpolator动画匀速改变
OvershootInterpolator@android:anim/overshoot_interpolator向前弹出一定值之后回到原来位置
PathInterpolator新增,定义路径坐标后按照路径坐标来跑。

6.1、插值器的使用

使用如下:

<set android:interpolator="@android:anim/accelerate_interpolator">
    ...
</set>

6.2、插值器的自定义

有时候你会发现系统提供的插值器不够用,可能就像View一样需要自定义。所以接下来我们来看看插值器的自定义,关于插值器的自定义分为两种实现方式,xml自定义实现(其实就是对现有的插值器的一些属性修改)或者java代码实现方式。如下我们来说说。

先看看XML自定义插值器的步骤:

  • 在res/anim/目录下创建filename.xml文件。

  • 修改你准备自定义的插值器如下:

    <?xml version="1.0" encoding="utf-8"?>
    <InterpolatorName xmlns:android="/apk/res/android"
        android:attribute_name="value"
        />

    在你的补间动画文件中引用该文件即可

    可以看见上面第二步修改的是现有插值器的一些属性,但是有些插值器却不具备修改属性,具体如下:

    accelerateDecelerateInterpolator

    无可自定义的attribute。

    accelerateInterpolator

    android:factor 浮点值,加速速率(默认值为1)。

    anticipateInterploator

    android:tension 浮点值,起始点后拉的张力数(默认值为2)。

    anticipateOvershootInterpolator

    android:tension 浮点值,起始点后拉的张力数(默认值为2)。 android:extraTension 浮点值,拉力的倍数(默认值为1.5)。

    bounceInterpolator

    无可自定义的attribute。

    cycleInterplolator

    android:cycles 整形,循环的个数(默认为1)。

    decelerateInterpolator

    android:factor 浮点值,减速的速率(默认为1)。

    linearInterpolator

    无可自定义的attribute。

    <overshootInterpolator>

    android:tension 浮点值,超出终点后的张力(默认为2)。

    再来看看Java自定义插值器的(Java自定义插值器其实是xml自定义的升级,也就是说如果我们修改xml的属性还不能满足需求,那就可以选择通过Java来实现)方式。

    可以看见上面所有的Interpolator都实现了Interpolator接口,而Interpolator接口又继承自 TimeInterpolator,TimeInterpolator接口定义了一个float getInterpolation(float input);方法,这个方法是由系统调用的,其中的参数input代表动画的时间,在0和1之间,也就是开始和结束之间。

    如下就是一个动画始末速率较慢、中间加速的AccelerateDecelerateInterpolator插值器:

    public class AccelerateDecelerateInterpolator extends BaseInterpolator
            implements NativeInterpolatorFactory {
        ......
        public float getInterpolation(float input) {
            return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
        }
        ......
    }

    到此整个补间动画与补间动画的插值器都分析完毕了,接下来看下别的动画。

二、帧动画

帧动画(Frame动画)也称作Drawable动画。

它允许像播放幻灯片一样的效果,这种动画实质是drawable,所以这种动画的定义方式文件医保放在res/drawable/目录下。

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false">
    <item android:drawable="@mipmap/refresh_loading01" android:duration="100" />
    <item android:drawable="@mipmap/refresh_loading02" android:duration="100" />
    <item android:drawable="@mipmap/refresh_loading03" android:duration="100" />
    <item android:drawable="@mipmap/refresh_loading04" android:duration="100" />
    <item android:drawable="@mipmap/refresh_loading05" android:duration="100" />
    <item android:drawable="@mipmap/refresh_loading06" android:duration="100" />
    <item android:drawable="@mipmap/refresh_loading07" android:duration="100" />
    <item android:drawable="@mipmap/refresh_loading08" android:duration="100" />
    <item android:drawable="@mipmap/refresh_loading09" android:duration="100" />
    <item android:drawable="@mipmap/refresh_loading10" android:duration="100" />
    <item android:drawable="@mipmap/refresh_loading11" android:duration="100" />
    <item android:drawable="@mipmap/refresh_loading12" android:duration="100" />
</animation-list>

在java中使用

AnimationDrawable animDrawable = (AnimationDrawable) ContextCompat.getDrawable(mCtx, R.drawable.anim_loading_view);
animationDrawable.start();
imageView.setImageDrawable(animationDrawable);

*特别注意,AnimationDrawable的start()方法不能在Activity的onCreate方法中调运,因为AnimationDrawable还未完全附着到window上,所以最好的调运时机是onWindowFocusChanged()方法中。*

三、属性动画(Property Animation

1、属性动画简介

Android3.0以后引入了属性动画,属性动画可以轻而易举的实现许多View动画做不到的事,譬如3D旋转一张图片。属性动画实现原理就是修改控件的属性值实现的动画

所有的属性动画的抽象基类就是Animator

java类名xml关键字描述信息
ValueAnimator<animator>放置在res/animator/目录下在一个特定的时间里执行一个动画
TimeAnimator不支持/点我查看原因时序监听回调工具
ObjectAnimator<objectAnimator>放置在res/animator/目录下一个对象的一个属性动画
AnimatorSet<set>放置在res/animator/目录下动画集合

所以可以看见,我们平时使用属性动画的重点就在于AnimatorSet、ObjectAnimator、TimeAnimator、ValueAnimator。

2、Java代码实现对象动画

首先我们先来看一下ObjectAnimator类最基本的方法

public static ObjectAnimator ofFloat(Object target, String propertyName, float... values) {
        ObjectAnimator anim = new ObjectAnimator(target, propertyName);
        anim.setFloatValues(values);
        return anim;
    }

方法中第一个参数Object target 的作用对象通常是View,也就是Android中的控件或布局。 方法中第二个参数String propertyName 通常是需要执行动画的属性,具体值如下表所示

属性值的用法
rotation以屏幕方向为轴的旋转度数
alpha透明度
translationX / translationYX/Y方向的位移
scaleX /scaleYX/Y方向的缩放倍数
rotationX / rotationY以X/Y轴为轴的旋转度数

方法中第三个参数float... values 表示属性的变换范围,该参数可以传多个值。

添加一些代码来看一下效果

ImageView imageView = findViewById(R.id.imageView);
ObjectAnimator animator = ObjectAnimator.ofFloat(imageView, "alpha", 1f, 0f, 1f);
animator.setDuration(5000);
animator.start();

该动画效果表示控件ImageView的透明度在5s内由1变换到0,再由0变回 1

ObjectAnimator的其他方法使用如下:

ImageView imageView = findViewById(R.id.imageView);
 ObjectAnimator animator = ObjectAnimator.ofFloat(imageView, "alpha", 1f, 0f, 1f);
 animator.setDuration(2000);
​
 //动画延迟500ms执行
 animator.setStartDelay(500);
​
 //执行重复次数 +1
 animator.setRepeatCount(3);
​
 // 设置动画重复播放模式 RESTART -执行完一遍后重新执行
 // REVERSE -执行完一遍后 从末位置往前执行
 animator.setRepeatMode(ValueAnimator.RESTART);
​
 //监听值变换
 animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
     @Override
     public void onAnimationUpdate(ValueAnimator animation) {
         Log.i("MainActivity","value:" +animation.getAnimatedValue());
     }
 });
 animator.start();

3、XML实现对象动画

  • res目录下新建animator文件夹

  • animator文件夹下创建动画XML文件,如`animator_alpha.xml

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:propertyName="alpha"
    android:valueFrom="1"
    android:valueTo="0"
    android:valueType="floatType" />

在xml中可直接用的属性动画节点有ValueAnimator、ObjectAnimator、AnimatorSet

<set  android:ordering=["together" | "sequentially"]>
    <objectAnimator
        android:propertyName="string"
        android:duration="int"
        android:valueFrom="float | int | color"
        android:valueTo="float | int | color"
        android:startOffset="int"
        android:repeatCount="int"
        android:repeatMode=["repeat" | "reverse"]
        android:valueType=["intType" | "floatType"]/>
​
    <animator
        android:duration="int"
        android:valueFrom="float | int | color"
        android:valueTo="float | int | color"
        android:startOffset="int"
        android:repeatCount="int"
        android:repeatMode=["repeat" | "reverse"]
        android:valueType=["intType" | "floatType"]/>
​
    <set>
    ...
    </set>
</set>

<set>属性解释

xml属性解释
android:ordering控制子动画启动方式是先后有序的还是同时进行。sequentially:动画按照先后顺序;together(默认):动画同时启动;

<objectAnimator>属性解释:

xml属性解释
android:propertyNameString类型,必须要设置的节点属性,代表要执行动画的属性(通过名字引用),辟如你可以指定了一个View的”alpha” 或者 “backgroundColor” ,这个objectAnimator元素没有对外说明target属性,所以你不能在XML中设置执行这个动画,必须通过调用 loadAnimator()方法加载你的XML动画资源,然后调用setTarget()应用到具备这个属性的目标对象上(譬如TextView)。
android:valueTofloat、int或者color类型,必须要设置的节点属性,表明动画结束的点;如果是颜色的话,由6位十六进制的数字表示。
android:valueFrom相对应valueTo,动画的起始点,如果没有指定,系统会通过属性的get方法获取,颜色也是6位十六进制的数字表示。
android:duration动画的时长,int类型,以毫秒为单位,默认为300毫秒。
android:startOffset动画延迟的时间,从调用start方法后开始计算,int型,毫秒为单位。
android:repeatCount一个动画的重复次数,int型,”-1“表示无限循环,”1“表示动画在第一次执行完成后重复执行一次,也就是两次,默认为0,不重复执行。
android:repeatMode重复模式:int型,当一个动画执行完的时候应该如何处理。该值必须是正数或者是-1,“reverse”会使得按照动画向相反的方向执行,可实现类似钟摆效果。“repeat”会使得动画每次都从头开始循环。
android:valueType关键参数,如果该value是一个颜色,那么就不需要指定,因为动画框架会自动的处理颜色值。有intType和floatType(默认)两种:分别说明动画值为int和float型。

Java代码中通过加载该xml启动动画

ImageView imageView = findViewById(R.id.imageView);
Animator anim = AnimatorInflater.loadAnimator(mCtx.this,R.animator.animator);
anim.setTarget(imageView);
anim.start();

4、值动画(ValueAnimator)

值动画通过控制值的变化,之后 手动赋值给对象的属性,从而实现动画。

ValueAnimator的核心方法如下:

ValueAnimator ofFloat(float... values) -- 浮点型数值
ValueAnimator  ofInt(int... values) -- 整型数值
ValueAnimator  ofObject(TypeEvaluator evaluator, Object... values) -- 自定义对象类型

下面我们来添加值动画,在值动画的监听函数里 来获取值得变化,根据值的变化对控件设置相应的属性。这里的属性可以是控件的任意属性

 final ImageView imageView = findViewById(R.id.imageView);
 ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
 anim.setDuration(5000);
 anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
     @Override
     public void onAnimationUpdate(ValueAnimator animation) {
         float currentValue = (float) animation.getAnimatedValue();
         Log.d("MainActivity", "cuurent value is " + currentValue);
         imageView.setAlpha(currentValue);
     }
 });
 anim.start();

5、PropertyValueHolder

PropertyValueHolder可以让前面的一些动画同时执行。

 ImageView imageView = findViewById(R.id.imageView);
 PropertyValuesHolder alphaProper = PropertyValuesHolder.ofFloat("alpha", 0.5f, 1f);
 PropertyValuesHolder scaleXProper = PropertyValuesHolder.ofFloat("scaleX", 0f, 1f);
 PropertyValuesHolder scaleYProper = PropertyValuesHolder.ofFloat("scaleY", 0f, 1f);
 PropertyValuesHolder translationXProper = PropertyValuesHolder.ofFloat("translationX", -100, 100);
 PropertyValuesHolder translationYProper = PropertyValuesHolder.ofFloat("translationY", -100, 100);
 PropertyValuesHolder rotationProper = PropertyValuesHolder.ofFloat("rotation", 0, 360);
 ValueAnimator animator = ObjectAnimator.ofPropertyValuesHolder(imageView, alphaProper,
         scaleXProper, scaleYProper,translationXProper,translationYProper,rotationProper);
 animator.setDuration(5000);
 animator.start();

6、动画组合(AnimatorSet)

前面的PropertyValueHolder类能实现将多个动画同时执行,AnimatorSet不仅能让多个动画同时执行,还能让多个动画按一定的顺序执行,同时也能穿插多个动画同时执行。 主要的方法如下:

after(Animator anim) 将现有动画插入到传入的动画之后执行 after(long delay) 将现有动画延迟指定毫秒后执行 before(Animator anim) 将现有动画插入到传入的动画之前执行 with(Animator anim) 将现有动画和传入的动画同时执行

 ImageView imageView = findViewById(R.id.imageView);
 ObjectAnimator rotate = ObjectAnimator.ofFloat(imageView, "rotation", 0f, 360f);
 ObjectAnimator translationX = ObjectAnimator.ofFloat(imageView, "translationX", -100, 100f);
 ObjectAnimator translationY = ObjectAnimator.ofFloat(imageView, "translationY", -100, 100f);
 ObjectAnimator scaleX = ObjectAnimator.ofFloat(imageView, "scaleX", 0, 1f);
 ObjectAnimator scaleY = ObjectAnimator.ofFloat(imageView, "scaleY", 0, 1f);
 ObjectAnimator alpha = ObjectAnimator.ofFloat(imageView, "alpha", 1f, 0f, 1f);
 AnimatorSet animSet = new AnimatorSet();
 animSet.play(rotate)
         .with(alpha)
         .after(scaleX)
         .before(translationX)
         .after(1000)
         .before(translationY)
         .with(scaleY);
 animSet.setDuration(5000);
 animSet.start();
​

7、插值器

animator.setInterpolator(new AccelerateInterpolator(5));

8、估值器(TypeEvaluator)

在前面的值动画(ValueAnimator)中和对象动画(ObjectAnimator)有一个传对象的方法:

ValueAnimator  ofObject(TypeEvaluator evaluator, Object... values)
ObjectAnimator ofObject(Object target, String propertyName,
            TypeEvaluator evaluator, Object... values)
MyView imageView = findViewById(R.id.myview);
ObjectAnimator anim = ObjectAnimator.ofObject(
        imageView,"color", new MyTypeEvaluator(),
        "#0000FF","#FF0000");
anim.setDuration(5000);
anim.start();
  • IntEvaluator:整数属性值。

  • FloatEvaluator:浮点数属性值。

  • ArgbEvaluator:十六进制color属性值。

  • TypeEvaluator:用户自定义属性值接口,譬如对象属性值类型不是int、float、color类型,你必须实现这个接口去定义自己的数据类型。

9、Java属性动画拓展之ViewPropertyAnimator动画

在Android API 12时,View中添加了animate方法,具体如下:

public class View implements Drawable.Callback, KeyEvent.Callback,        AccessibilityEventSource {     ......    
    /**     
     * This method returns a ViewPropertyAnimator object, which can be used to animate        * specific properties on this View.     
     *     
     * @return ViewPropertyAnimator The ViewPropertyAnimator associated with this View.      */    
    public ViewPropertyAnimator animate() {        
        if (mAnimator == null) {            
            mAnimator = new ViewPropertyAnimator(this);        
        }        
        return mAnimator;    
    }                                                                                           ......                                                                             }

可以看见通过View的animate()方法可以得到一个ViewPropertyAnimator的属性动画(有人说他没有继承Animator类,是的,他是成员关系,不是之前那种继承关系)。

ViewPropertyAnimator提供了一种非常方便的方法为View的部分属性设置动画(切记,是部分属性),它可以直接使用一个 Animator对象设置多个属性的动画;在多属性设置动画时,它比 上面的ObjectAnimator更加牛逼、高效,因为他会管理多个属性的invalidate方法统一调运触发,而不像上面分别调用,所以还会有一些 性能优化。如下就是一个例子:

myView.animate().x(0f).y(100f).start();

10、Java属性动画拓展之LayoutAnimator容器布局动画

Property动画系统还提供了对ViewGroup中View添加时的动画功能,我们可以用LayoutTransition对 ViewGroup中的View进行动画设置显示。LayoutTransition的动画效果都是设置给ViewGroup,然后当被设置动画的 ViewGroup中添加删除View时体现出来。该类用于当前布局容器中有View添加、删除、隐藏、显示等时候定义布局容器自身的动画和View的动 画,也就是说当在一个LinerLayout中隐藏一个View的时候,我们可以自定义 整个由于LinerLayout隐藏View而改变的动画,同时还可以自定义被隐藏的View自己消失时候的动画等。

我们可以发现LayoutTransition类中主要有五种容器转换动画类型,具体如下:

  • LayoutTransition.APPEARING:当View出现或者添加的时候View出现的动画。

  • LayoutTransition.CHANGE_APPEARING:当添加View导致布局容器改变的时候整个布局容器的动画。

  • LayoutTransition.DISAPPEARING:当View消失或者隐藏的时候View消失的动画。

  • LayoutTransition.CHANGE_DISAPPEARING:当删除或者隐藏View导致布局容器改变的时候整个布局容器的动画。

  • LayoutTransition.CHANGE:当不是由于View出现或消失造成对其他View位置造成改变的时候整个布局容器的动画。

XML方式使用系统提供的默认LayoutTransition动画:

我们可以通过如下方式使用系统提供的默认ViewGroup的LayoutTransition动画:

android:animateLayoutChanges=”true”

在ViewGroup添加如上xml属性默认是没有任何动画效果的,因为前面说了,该动画针对于ViewGroup内部东东发生改变时才有效,所以当我们设置如上属性然后调运ViewGroup的addView、removeView方法时就能看见系统默认的动画效果了。

还有一种就是通过如下方式设置:

android:layoutAnimation=”@anim/customer_anim”

通过这种方式就能实现很多吊炸天的动画。

Java方式使用系统提供的默认LayoutTransition动画:

在使用LayoutTransition时,你可以自定义这几种事件类型的动画,也可以使用默认的动画,总之最终都是通过 setLayoutTransition(LayoutTransition lt)方法把这些动画以一个LayoutTransition对象设置给一个ViewGroup。

譬如实现如上Xml方式的默认系统LayoutTransition动画如下:

mTransitioner = new LayoutTransition();
mViewGroup.setLayoutTransition(mTransitioner);

稍微再高端一点吧,我们来自定义这几类事件的动画,分别实现他们,那么你可以像下面这么处理:

mTransitioner = new LayoutTransition();
......
ObjectAnimator anim = ObjectAnimator.ofFloat(this, "scaleX", 0, 1);
......//设置更多动画
mTransition.setAnimator(LayoutTransition.APPEARING, anim);
......//设置更多类型的动画                mViewGroup.setLayoutTransition(mTransitioner);

到此通过LayoutTransition你就能实现类似小米手机计算器切换普通型和科学型的炫酷动画了。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐