layout: post
title: Android群英传-第七章 Android动画机制与使用技巧
date: 2015-12-12
categories: blog
tags: [Android,Animation,Animator]
category: Android
description: 总结常用的5中View动画,属性动画,ViewGroup加载动画,Activity跳转动画
代码地址
View动画
所有类都继承自Animation
-
AplhaAnimation
AlphaAnimation alphaAnimation = new AlphaAnimation(1, 0); alphaAnimation.setDuration(2000); v.startAnimation(alphaAnimation);
-
TransationAnimation
TranslateAnimation translateAnimation = new TranslateAnimation(0, 100, 0, 100); translateAnimation.setDuration(2000); v.startAnimation(translateAnimation);
-
SacleAnimation
ScaleAnimation scaleAnimation = new ScaleAnimation(1, 0, 1, 0); scaleAnimation.setDuration(2000); v.startAnimation(scaleAnimation);
-
RotateAnimation
RotateAnimation rotateAnimation = new RotateAnimation(0, 180, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f); rotateAnimation.setDuration(2000); v.startAnimation(rotateAnimation);
-
AnimationSet
AnimationSet animationSet = new AnimationSet(true); RotateAnimation rotate = new RotateAnimation(0, 180, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f); rotate.setDuration(2000); ScaleAnimation scale = new ScaleAnimation(1, 0, 1, 0); scale.setDuration(2000); animationSet.addAnimation(scale); animationSet.addAnimation(rotate); v.startAnimation(animationSet);
<i>记忆</i>:这里的动画是Animation这个单词,和属性动画的Animator是不同的,别混淆,缩放动画
ScaleAnimation
和旋转RotateAnimation
需要设置锚点,可以是相对View本身.
<i>注意</i>:View Animation只是改变了View的绘制,没有改变其属性,比如缩放动画,视图看起来是大小变化了,但是getWidth()
取得的值是不会变化的,并且它的View.setonClickListener(...)
响应的位置仍然是原位置,不是改变后的位置.
属性动画
-
ValueAnimator
ValueAnimator本身不提供动画效果,
ObjectAnimtor
也是继承至ValueAnimator的,他提供一个数值变化的监听,通过监听数值的变化自己实现响应的动画效果ValueAnimator valueAnimator = ValueAnimator.ofInt(0, 1000); valueAnimator.setDuration(2000); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { Log.v(TAG, animation.getAnimatedValue() + ""); v.getLayoutParams().width = (int) animation.getAnimatedValue(); v.requestLayout(); } }); valueAnimator.start();
-
AnimatorSet
AnimtorSet提供一个动画集合来处理动画效果,他提供一系列的操作来处理动画的顺序,
AnimatorSet animatorSet = new AnimatorSet(); PropertyValuesHolder holder3 = PropertyValuesHolder.ofFloat("translationX", 100); PropertyValuesHolder holder4 = PropertyValuesHolder.ofFloat("scaleX", 0, 1f); ObjectAnimator objectAnimatorSet2 = ObjectAnimator.ofPropertyValuesHolder(v, holder3, holder4); objectAnimatorSet2.setDuration(2000); animatorSet.play(objectAnimatorSet2); ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(v, "x", 100); animatorSet.playTogether(objectAnimator1); animatorSet.start();
除此之外ObjectAnimot也可以同时播放几个动画
PropertyValuesHolder holder1 = PropertyValuesHolder.ofFloat("translationX", 100); PropertyValuesHolder holder2 = PropertyValuesHolder.ofFloat("scaleX", 0, 1f); ObjectAnimator objectAnimatorSet = ObjectAnimator.ofPropertyValuesHolder(v, holder1, holder2); objectAnimatorSet.setDuration(2000); objectAnimatorSet.start();
-
ObjectAnimator
ObjectAnimator objectAnimator = ObjectAnimator.ofInt(v, "translationX", 300); objectAnimator.setDuration(2000); objectAnimator.start();
以上方法适用于含有
setter
和getter
的属性,若操作对象不含操作属性的getter
和setter
方法,如果不含需要自己包装.需要注意使用ObjectAnimator.ofInt(...)
之后在定义的包装器的setter
和getter
要与之类型对应.ObjectAnimator objectAnimator = ObjectAnimator.ofInt(new WrapperView(v), "width", 300); objectAnimator.setDuration(2000); objectAnimator.start();
实现包装:
private static class WrapperView { private View target; public WrapperView(View target) { this.target = target; } public void setWidth(int width) { target.getLayoutParams().width = width; target.requestLayout(); } public int getWidth() { return target.getLayoutParams().width; } }
ViewGroup加载child时的动画
-
XML方式
android:animateLayoutChanges="true"
该种方式只会使用系统默认的动画,用户不能定制 -
Java
AlphaAnimation alphaAnimation = new AlphaAnimation(0, 1); alphaAnimation.setDuration(2000); LayoutAnimationController controller = new LayoutAnimationController(alphaAnimation, 0.5f); controller.setOrder(LayoutAnimationController.ORDER_NORMAL);//包括三种,正常,随机,反序 layout.setLayoutAnimation(controller);
Android 5+ 特性
-
填充效果
int cx = v.getWidth() / 2; int cy = v.getHeight() / 2; int finalRadius = Math.max(v.getWidth(), v.getHeight()); Animator anim = ViewAnimationUtils.createCircularReveal(v, cx, cy, 0, finalRadius); v.setVisibility(View.VISIBLE); anim.start();
这就是在Android 5.+上面按钮等组件默认的动画效果
-
Activity间的过渡动画
在Android5.0之前,Activity之间的动画是通过函数
overridePendingTransition(Android.R.anim.fade_in, android.R.anim.fade_out);
实现的,但是他只是单独作用在每一Activity之上,并没有产生协同作用.
在Android5.0之后,有了新的方式来实现两个Activity之间的过渡Intent intent = new Intent(this, AnimTestActivity.class); startActivity(intent,ActivityOptions.makeSceneTransitionAnimation( this, v, "robot").toBundle());
在两个Activity上都存在一个包含属性
android:transitionName="robot"
的控件,比如类似下面的格式.
<TextView android:id="@+id/activityBtn" android:transitionName="robot" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Activity效果" />
当然,也可以同时共享多个View.
ActivityOptions options = ctivityOptions.makeSceneTransitionAnimation(this, Pair.create(view1, "agreedName1"), Pair.create(view2, "agreedName2"));
-
待补充...