android 动画详解(二)
下面就开始学习属性动画的基本用法,我们来看属性动画的继承关系,如下如所示:

显然关注的焦点应该是ValueAnimator,ObjectAnimator这两个类啦,ObjectAnimator继承自ValueAnimator,是属性动画中非常重要的一个实现类,通过ObjectAnimator类的静态欧工厂方法来创建ObjectAnimator对象,这些静态工厂方法包括:ObjectAnimator.ofFloat(),ObjectAnimator.ofInt()等等,当然最为重要的一个静态工厂方法是ObjectAnimator.ofObject(),可以接收一个Object对象并为其设置属性动画,瞬间高大上了有木有?这些静态工厂方法接收的参数分别是:
要设置动画的目标对象;
动画的属性类型;
一个或多个属性值;当只指定一个属性值,系统默认此值为结束值;当指定两个属性值,系统默认分别为起始值和结束值;当指定三个或三个以上时,系统默认线性插值;
ValueAnimator是整个属性动画机制当中最核心的一个类,前面我们已经提到了,属性动画的运行机制是通过不断地对值进行操作来实现的,而初始值和结束值之间的动画过渡就是由ValueAnimator这个类来负责计算的,ValueAnimator对过渡动画值的计算依靠一个时间因子fraction,而这个时间因子fraction是系统由setDuration()方法设置的动画执行时间通过计算得来的,所以ValueAnimator还负责管理动画的持续时间、播放次数、播放模式、以及对动画设置监听器等,确实是一个非常重要的类。
相关API
Property Animation故名思议就是通过动画的方式改变对象的属性了,我们首先需要了解几个属性:
Duration动画的持续时间,默认300ms。
Time interpolation:时间差值,乍一看不知道是什么,但是我说LinearInterpolator、AccelerateDecelerateInterpolator,大家一定知道是干嘛的了,定义动画的变化率。
Repeat count and behavior:重复次数、以及重复模式;可以定义重复多少次;重复时从头开始,还是反向。
Animator sets: 动画集合,你可以定义一组动画,一起执行或者顺序执行。
Frame refresh delay:帧刷新延迟,对于你的动画,多久刷新一次帧;默认为10ms,但最终依赖系统的当前状态;基本不用管。
相关的类
ObjectAnimator 动画的执行类,后面详细介绍
ValueAnimator 动画的执行类,后面详细介绍
AnimatorSet 用于控制一组动画的执行:线性,一起,每个动画的先后执行等。
AnimatorInflater 用户加载属性动画的xml文件
TypeEvaluator 类型估值,主要用于设置动画操作属性的值。
TimeInterpolator 时间插值,上面已经介绍。
总的来说,属性动画就是,动画的执行类来设置动画操作的对象的属性、持续时间,开始和结束的属性值,时间差值等,然后系统会根据设置的参数动态的变化对象的属性。
ValueAnimator
ValueAnimator是整个属性动画机制当中最核心的一个类,属性动画的运行机制是通过不断地对值进行操作来实现的,而初始值和结束值之间的动画过渡就是由ValueAnimator这个类来负责计算的。它的内部使用一种时间循环的机制来计算值与值之间的动画过渡,我们只需要将初始值和结束值提供给ValueAnimator,并且告诉它动画所需运行的时长,那么ValueAnimator就会自动帮我们完成从初始值平滑地过渡到结束值这样的效果。除此之外,ValueAnimator还负责管理动画的播放次数、播放模式、以及对动画设置监听器等,确实是一个非常重要的类。
但是ValueAnimator的用法却一点都不复杂,我们先从最简单的功能看起吧,比如说想要将一个值从0平滑过渡到1,时长300毫秒,就可以这样写
ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
anim.setDuration(300);
anim.start();
很简单吧,调用ValueAnimator的ofFloat()方法就可以构建出一个ValueAnimator的实例,ofFloat()方法当中允许传入多个float类型的参数,这里传入0和1就表示将值从0平滑过渡到1,然后调用ValueAnimator的setDuration()方法来设置动画运行的时长,最后调用start()方法启动动画。
用法就是这么简单,现在如果你运行一下上面的代码,动画就会执行了。可是这只是一个将值从0过渡到1的动画,又看不到任何界面效果,我们怎样才能知道这个动画是不是已经真正运行了呢?这就需要借助监听器来实现了,如下所示:
ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
anim.setDuration(300);
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float currentValue = (float) animation.getAnimatedValue();
Log.d("TAG", "cuurent value is " + currentValue);
}
});
anim.start()
ObjectAnimator
相比于ValueAnimator,ObjectAnimator可能才是我们最常接触到的类,因为ValueAnimator只不过是对值进行了一个平滑的动画过渡,但我们实际使用到这种功能的场景好像并不多。而ObjectAnimator则就不同了,它是可以直接对任意对象的任意属性进行动画操作的;
下面举几个例子(csdn上面的例子)
一个动画能够让View既可以缩小、又能够淡出(3个属性scaleX,scaleY,alpha),只使用ObjectAnimator咋弄?
public void rotateyAnimRun(final View view)
{
ObjectAnimator anim = ObjectAnimator//
.ofFloat(view, "zhy", 1.0F, 0.0F)//
.setDuration(500);//
anim.start();
anim.addUpdateListener(new AnimatorUpdateListener()
{
@Override
public void onAnimationUpdate(ValueAnimator animation)
{
float cVal = (Float) animation.getAnimatedValue();
view.setAlpha(cVal);
view.setScaleX(cVal);
view.setScaleY(cVal);
}
});
}
其实还有更简单的方式,实现一个动画更改多个效果:使用propertyValuesHolder
public void propertyValuesHolder(View view)
{
PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("alpha", 1f,
0f, 1f);
PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("scaleX", 1f,
0, 1f);
PropertyValuesHolder pvhZ = PropertyValuesHolder.ofFloat("scaleY", 1f,
0, 1f);
ObjectAnimator.ofPropertyValuesHolder(view, pvhX, pvhY,pvhZ).setDuration(1000).start();
}
//AnimatorSet
ObjectAnimator moveIn = ObjectAnimator.ofFloat(textview, "translationX", -500f, 0f);
ObjectAnimator rotate = ObjectAnimator.ofFloat(textview, "rotation", 0f, 360f);
ObjectAnimator fadeInOut = ObjectAnimator.ofFloat(textview, "alpha", 1f, 0f, 1f);
AnimatorSet animSet = new AnimatorSet();
animSet.play(rotate).with(fadeInOut).after(moveIn);
animSet.setDuration(5000);
animSet.start();
vcS/x7DOqta5o6xPYmplY3RBbmltYXRvcrXE08O3qLu5y+PKx8/gtbG88rWlsMmjrLWrysfO0s/g0MW/z7aou+HT0LK7ydnF89PRz9bU2tDEwO+2vNPQzazR+dK7uPbSyc7Ko6y+zcrHb2ZGbG9hdCgpt723qLXEtdq2/rj2ss7K/bW9tde/ydLUtKvExNCp1rXE2KO/xL/HsM7Sw8fKudPDuf3By2FscGhhoaJyb3RhdGlvbqGidHJhbnNsYXRpb25Yus1zY2FsZVnV4ry4uPbWtaOst9ax8L/J0tTN6rPJta3I67Wts/ahotD916qhosuuxr3SxravoaK0udaxy/W3xdXivLjW1ravu62jrMTHw7S7udPQxMTQqda1yse/ydLUyrnTw7XExNijv8bkyrXV4rj2zsrM4rXEtPCwuLfHs6PQ/rr1o6y+zcrHztLDx7/J0tS0q8jryM7S4rXE1rW1vW9mRmxvYXQoKbe9t6i1xLXatv649rLOyv21sdbQoaPIztLitcTWtaO/z+DQxdXiutyz9rr1tPO80rXE0uLBz7DJo6y1q8rCyrW+zcrHyOe0y6Gj0vLOqk9iamVjdEFuaW1hdG9y1NrJ6LzGtcTKsbryvs3Du9PQ1eu21NPaVmlld8C0vfjQ0MnovMajrLb4ysfV67bU09rIztLittTP87XEo6zL/Mv5uLrU8LXEuaTX977Nyseyu7bPtdjP8sSzuPa21M/z1tC1xMSzuPbK9NDUvfjQ0Liz1rWjrMi7uvO21M/zuPm+3cr00NTWtbXEuMSx5NTZwLS+9raoyOe6ztW5z9az9sC0oaM8YnIgLz4NCsTHw7SxyMjny7XO0sPHtffTw8/Cw+bV4tH50ru2zrT6wuujujwvcD4NCjxwcmUgY2xhc3M9"brush:java;">
ObjectAnimator.ofFloat(textview, "alpha", 1f, 0f);
其实这段代码的意思就是ObjectAnimator会帮我们不断地改变textview对象中alpha属性的值,从1f变化到0f。然后textview对象需要根据alpha属性值的改变来不断刷新界面的显示,从而让用户可以看出淡入淡出的动画效果。
那么textview对象