对Animation中的fillAfter,fillBefore,fillEnabled的理解

Animation

Animation是一个抽象类,它的直接子类有AlphaAnimation,ScaleAnimation,RotateAnimation,TranslateAnimation,AnimationSet。

Animation所具有的属性有以下几个:

android:duration           动画持续时间,以毫秒为单位 
android:fillAfter          用于确定是否保持动画结束时的值,如果设置为true,控件动画结束时,将保持动画                           最后时的状态,为false就是不保持
android:fillBefore         用于确定动画开始时,View的动画属性值;这里所说的动画开始不是指的调用                                startAnimation方法,而是界面中动画真正开始动的时候。从调用                                    startAnimation到动画真正开始时,中间有一个startOffset阶段,若
                           fillBefore为true,则在startOffset阶段时,将动画属性设置为初始值,
                           为false,则为View本身的初始值。
android:fillEnabled        用来控制fillBefore属性是否有效,若为true,则fillBefore生效;若为false
                           则不管设置fillBefore为true还是false,都不起作用。但是,划重点了,当
                           fillEnabled为false时,我们假设fillBefore为true。也就是说,当                                   fillEnabled为false是,不管fillBefore是什么值,在startOffset阶段
                           都将初始值设置为动画属性的初始值。
android:repeatCount        重复次数
android:repeatMode         重复类型,有reverse和restart两个值,reverse表示倒序回放,restart表示重                           新放一遍,必须与repeatCount一起使用才能看到效果。因为这里的意义是重复的类                           型,即回放时的动作。
android:interpolator       设定插值器,其实就是指定的动作效果,比如弹跳效果等。

本文主要讲fillAfter,fillBefore,fillEnabled三者之间的关系,其实上面已经讲得很清楚了,如果是表述不清,还请指出,多谢。结论已经给出来了,按照惯例,还是给个例子,加深一下印象。下面我就通过两个示例来证明一下上述结论。一个根节点为单个动画,一个根节点为组合动画:

ScaleAnimation
src/main/res/anim/scaleanim.xml


Java代码中任意实例化一个View对象,我这里的View对象targetView,是然后

Animation animation = AnimationUtils.loadAnimation(context,R.anim.scaleanim);
targetView.startAnimation(animation);

偏移的时间量为3秒,也就是说动画正真开始的时间是调用startAnimation方法的3秒后。然后在3秒的时间内,View是怎么样一个状态呢,可以看到示例中fillEnabled为true,所以fillBefore是有效的,fillBefore为false,所以最终运行的结果是调用loadAnimation后,View保存View本身的一个初始大小,而并不会放大为本身的2倍,持续3秒后,立刻变为原来的2倍,然后开始动画,慢慢变为原来的3倍,然后回到初始大小,动画停止。

这里并没有设置fillAfter,fillAfter其实和fillBefore和fillEnabled没有什么关系,fillAfter的默认值为false,所以动画结束后会回到原来的大小。

fillBefore,fillEnabled到底用在哪些地方呢,看下一个示例吧

AnimationSet


    
    

在组合动画中,我们可以通过设置fillBefore,fillEnabled来保证得到你想要的一个效果。我需要View先在原位置从0.5倍放大到2倍,然后在从原位置的90度旋转到720度。要怎么做呢?假如将上面的fillEnabled,fillBefore删掉,动画是一个什么效果呢?

补充一下,在Animation源码中可以看到,fillAfter的默认值为false,fillBefore的默认值为true,fillEnabled默认值为false。如果不设置这几个值,即为默认值。fillEnabled为false时,fillBefore的值就无所谓了,但是系统会假设fillBefore为true。所以将上面的fillBefore,fillEnabled删掉后的结果是:初始状态为View偏90度,大小为View本身大小的一半,在接下来的1秒内变为View本身大小的2倍,然后,再在接下来的2秒内旋转到720度的位置,最后变为View本身的大小

那么要达到想要的效果,就可以通过设置fillEnabled,fillEnabled来实现。View先在原位置从0.5倍放大到2倍,也就是说此时View的初始状态不可以旋转90度,则rotate标签中把fillEnabled设置为true,因为fillBefore,fillAfter是在set标签中设置。View从0.5倍放大到2倍说明View的初始大小为View本身大小的0.5倍。所以将fillEnabled设置为false,因为fillEnabled为false其实就相当于fillEnabled,fillBefore为同时为true的效果。

总结一下:fillEnabled为false、fillBefore为any相当于fillEnabled为true且fillBefore为true

通常在set标签中fillBefore设置为false,然后再动画结点中设置fillEnabled来确定在startOffset阶段是否使用给定初始值。

你可能感兴趣的:(对Animation中的fillAfter,fillBefore,fillEnabled的理解)