android开发(安卓动画之属性动画(一))

我们都知道安卓有三种动画,补间动画、帧动画、属性动画
补间动画有四种效果:平移(translate)、旋转(rotate)、缩放(scale)、透明(alpha),虽然补间动画可以完成一些简单的动画,但是它也有缺点:补间动画只改变了View的视觉效果,而没有改变View的属性。像你使用平移(translate)动画去移动view,它只是视图上看起来移动,但其实焦点还是会停留在原地,因此点击事件也是停留在原来的位置。再比如我们想使用动画修改view的背景颜色,补间动画就完成不了,所以引入属性动画这个概念。
属性动画是修改对象的属性来改变状态,它可以作用于任何对象
使用属性动画实现透明度渐变:

ObjectAnimator animator5 = ObjectAnimator.ofFloat(button, "alpha", 1); AnimatorSet animatorSet = new AnimatorSet(); animatorSet.play(animator5 ); animatorSet.setDuration(2000).start();

android开发(安卓动画之属性动画(一))
文章图片

ObjectAnimator.ofFloat()三个参数:
1.作用的对象(一般是我们的view)
2.动画作用的属性(对象必须提供这个属性的set、get方法)
3.动画达到的效果
setDuration():设置动画时长
start ( ):开始动画
使用属性动画实现平移:
ObjectAnimator animator3 = ObjectAnimator.ofFloat(button, "translationX", 500); AnimatorSet animatorSet = new AnimatorSet(); animatorSet.play(animator3); animatorSet.setDuration(2000).start();

使Button在X轴平移500个像素
android开发(安卓动画之属性动画(一))
文章图片

使用属性动画改变宽度:
ViewWrapper wrapper = new ViewWrapper(button); ObjectAnimator animator1 = ObjectAnimator.ofInt(wrapper, "width", 500); private static class ViewWrapper { private View mTarget; public ViewWrapper(View target) { mTarget = target; }public int getWidth() { return mTarget.getLayoutParams().width; }public void setWidth(int width) { mTarget.getLayoutParams().width = width; mTarget.requestLayout(); }

上文我们说到作用的属性需要提供get和set方法,但是view的setWidth()并不是设置自身的宽度,具体可以看源码。所以我们需要使用一个包装类来包装。ViewWrapper 包含了一个view成员变量,我们把Button传进去,并实现set、get方法。
ObjectAnimator.ofInt(wrapper, “width”, 500); 作用的是ViewWrapper 对象,而且get和set方法实现的是获取它的成员view的宽度和设置宽度
android开发(安卓动画之属性动画(一))
文章图片

使用属性动画改变背景颜色:
ObjectAnimator animator6 = ObjectAnimator.ofInt(button, "backgroundColor", Color.RED, Color.BLUE); //必须设置 animator6.setEvaluator(new ArgbEvaluator()); animatorSet.play(animator6); animatorSet.setDuration(2000).start();

【android开发(安卓动画之属性动画(一))】android开发(安卓动画之属性动画(一))
文章图片

使用属性动画同时作用同一个对象:
animatorSet调用playTogether()
animatorSet.playTogether(animator1, animator2, animator3, animator4, animator5, animator6); animatorSet.setDuration(2000).start();

android开发(安卓动画之属性动画(一))
文章图片

如果需要按顺序执行动画需要调用animatorSet的playSequentially()方法
属性动画链式表达式:
after:代表在指定动画执行完后再执行
with:代表同时执行动画
before:代表在指定动画之前执行
ViewWrapper wrapper = new ViewWrapper(button); //改变宽度 ObjectAnimator animator1 = ObjectAnimator.ofInt(wrapper, "width", 500); //改变高度 ObjectAnimator animator2 = ObjectAnimator.ofInt(wrapper, "height", 500); //平移 ObjectAnimator animator3 = ObjectAnimator.ofFloat(button, "translationX", 500); //旋转 ObjectAnimator animator4 = ObjectAnimator.ofFloat(button, "rotation", 90); //透明度 ObjectAnimator animator5 = ObjectAnimator.ofFloat(button, "alpha", 1); //背景颜色 ObjectAnimator animator6 = ObjectAnimator.ofInt(button, "backgroundColor", Color.RED, Color.BLUE); animator6.setEvaluator(new ArgbEvaluator()); AnimatorSet animatorSet = new AnimatorSet(); animatorSet.play(animator4).after(animator5).with(animator1).with(animator2); animatorSet.play(animator3).after(animator4); animatorSet.play(animator6).after(animator3); animatorSet.setDuration(2000).start(); private static class ViewWrapper { private View mTarget; public ViewWrapper(View target) { mTarget = target; }public int getWidth() { return mTarget.getLayoutParams().width; }public void setWidth(int width) { mTarget.getLayoutParams().width = width; mTarget.requestLayout(); }public int getHeight() { return mTarget.getLayoutParams().height; }public void setHeight(int height) { mTarget.getLayoutParams().height = height; mTarget.requestLayout(); } }

动画5和动画1和动画2同时执行
动画4在动画5和动画1和动画2同时执行完后执行
动画3在动画4执行完后执行
动画6在动画3执行完后执行
android开发(安卓动画之属性动画(一))
文章图片

    推荐阅读