why?
为什么使用动画,自从Android5.0以后,Google宣布了Material Design的设计语言,也增加了很多动画效果,使得app看起来更自然美观,交互体验更好。在我们的app里如果适当的使用动画的话,会给app带来更棒的交互体验,当然如果动画用的不合适或者滥用的话,也会带来更糟的体验。所以我们在了解动画机制的情况下适当的使用动画才是锦上添花。
这里提供Google对Material Design对介绍地址:https://material.io/guidelines/motion/material-motion.html#
Android中动画的分类
Android framework 提供了2中动画框架:属性动画和视图动画。两种动画框架都是可行的,但一般来说属性动画是首选的方法,因为它使用起来更灵活也提供了更多的特性,除了这两种动画框架,也可以使用帧动画(Drawable animation),帧动画允许加载并展示一张一张的可描绘资源组成动画。
Property Animation(属性动画)
属性动画是在Android3.0之后提供的动画,可以对一个对象的属性进行操作,从而达到动画的效果,包括没有被渲染到屏幕上的,该系统是可扩展的,让您可以将定制类型的属性进行动画化。
View Animation(视图动画)
视图动画是较老的系统,只能用于视图,设置和提供足够的能力来满足许多应用程序的需求是相对容易的
Drawable Animation(帧动画)
可绘制的动画需要一个接一个地显示可绘制的资源,就像胶卷一样。如果您希望用可绘制的资源来表示更容易表示的动画,比如位图的进展,那么这种动画方法是非常有用的。
视图动画与属性动画的区别(How Property Animation Differs from View Animation)
只能支持简单的缩放、平移、旋转、透明度基本的动画,且有一定的局限性。
视图动画系统的另一个缺点是它只修改了视图被绘制的地方,而不是实际的视图本身。例如对一个imageview添加事件后,平移那么事件还是会在之前的位置。
属性动画将不存在这些限制,您可以对任何对象(视图和非视图)的任何属性进行动画,并且对象本身实际上是被修改的。视图动画的使用比较简单。
属性动画的使用
ObjectAnimator
ObjectAnimator是属性动画框架中最重要的实行类,创建一个ObjectAnimator只需要通过静态工厂类直接返回一个ObjectAnimator对象即可。参数包含一个对象和对象的属性名字,但是这个属性必须有get和set函数,内部会通过反射机制来调用set函数修改对象的属性值。
例如:一个图片平移的动画
ObjectAnimator anim = ObjectAnimator
.ofFloat(view, "translationX", 300)
.setDuration(500);
anim.start();
通过这段代码就能使得这个view进行平移动画。
ofFloat源码:
public static <T> ObjectAnimator ofArgb(T target, Property<T, Integer> property,
int... values) {
ObjectAnimator animator = ofInt(target, property, values);
animator.setEvaluator(ArgbEvaluator.getInstance());
return animator;
}
第一个参数是我们要操纵的view,第二个参数是要操纵的属性。
最后一个是一个可变数组参数,需要穿进去该属性变化的一个取值过程,这里设置了一个参数,即变化到300。
常用的属性:
属性名称 | 属性描述 |
---|---|
translationX和translationY | 这两个属性作为一种增量来控制着view对象从它布局容器的左上角坐标偏移的位置 |
ratation,rotationX,rotationY | 这三个属性控制view对象围绕支点进行2D和3D旋转 |
scaleX,scaleY | 这两个属性控制着view对象围绕它的指点进行2D缩放 |
pivotX,pivotY | 这两个属性控制着view对象的支点位置,围绕这个支点进行旋转和缩放变换处理。默认情况下,该质点的位置就是view对象的中心点 |
x,y | 这两个简单实用的属性,它描述了view对象在它的容器中的最终位置,它是最初的组奥上交坐标和translationX,translationY值的累积和。 |
alpha | 它表示view对象的alpha透明度。默认值是1(不透明),0代表完全透明(不可见)。 |
ValueAnimator
ValueAnimator类允许您通过指定一组int、float或颜色值来激活动画的持续时间,从而监听数值的变化完成动画的变换。
ValueAnimator animation = ValueAnimator.ofFloat(0, 100);
animation.setTarget(view);
animation.setDuration(1000);
animation.start();
animation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
Float value = animation.getAnimatedFraction();
Log.e("tag", String.valueOf(value));
}
});
动画事件的监听
objectAnimator可以监听动画从开始到结束的四个过程。
anim.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
不过大部分时候我们需要关心动画结束时,所以可以直接这样:
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
}
});
AnimatorSet
AnimatorSet可以实现多种动画的展示。
AnimatorSet set=new AnimatorSet();
set.setDuration(1000);
set.playTogether(anim1,anim2);
set.start();
除了set.playTogether()方法,还有playSequentially(),set.play().with(),set.play().before(),set.play().after()等方法来控制多个动画的协同工作方式,从而控制顺序。
视图动画的使用
在3.0之前,视图动画是被广泛应用,但3.0后属性动画的出现,使得视图动画的缺点也就被放大了。主要一个缺点就是当视图移动后,其响应事件的位置还依然在动画前的地方,所以视图动画只能做普通的动画展示效果,避免交互的发生。
主要提供了AlphaAnimation,RotateAnimation,TranslateAnimation,ScaleAnimation四种动画方式,也提供了AnimationSet动画集合,混合使用多种动画。
RotateAnimation(旋转动画)
RotateAnimation rotateAnimation=new RotateAnimation(0,360,100,100);
rotateAnimation.setDuration(1000);
view.startAnimation(rotateAnimation);
参数分别为旋转的起始角度和旋转中心点的坐标。
TranslateAnimation(位移动画)
ScaleAnimation(缩放动画)
总结:其实每种动画的的使用方式基本相同,无非就是一些参数的特性不同。