layout: post
title: Android群英傳-第七章 Android動(dòng)畫機(jī)制與使用技巧
date: 2015-12-12
categories: blog
tags: [Android,Animation,Animator]
category: Android
description: 總結(jié)常用的5中View動(dòng)畫,屬性動(dòng)畫,ViewGroup加載動(dòng)畫,Activity跳轉(zhuǎn)動(dòng)畫
代碼地址
View動(dòng)畫
所有類都繼承自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>:這里的動(dòng)畫是Animation這個(gè)單詞,和屬性動(dòng)畫的Animator是不同的,別混淆,縮放動(dòng)畫
ScaleAnimation
和旋轉(zhuǎn)RotateAnimation
需要設(shè)置錨點(diǎn),可以是相對(duì)View本身.
<i>注意</i>:View Animation只是改變了View的繪制,沒有改變其屬性,比如縮放動(dòng)畫,視圖看起來是大小變化了,但是getWidth()
取得的值是不會(huì)變化的,并且它的View.setonClickListener(...)
響應(yīng)的位置仍然是原位置,不是改變后的位置.
屬性動(dòng)畫

-
ValueAnimator
ValueAnimator本身不提供動(dòng)畫效果,
ObjectAnimtor
也是繼承至ValueAnimator的,他提供一個(gè)數(shù)值變化的監(jiān)聽,通過監(jiān)聽數(shù)值的變化自己實(shí)現(xiàn)響應(yīng)的動(dòng)畫效果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
QQ截圖20151211163343.pngAnimtorSet提供一個(gè)動(dòng)畫集合來處理動(dòng)畫效果,他提供一系列的操作來處理動(dòng)畫的順序,
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也可以同時(shí)播放幾個(gè)動(dòng)畫
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
的屬性,若操作對(duì)象不含操作屬性的getter
和setter
方法,如果不含需要自己包裝.需要注意使用ObjectAnimator.ofInt(...)
之后在定義的包裝器的setter
和getter
要與之類型對(duì)應(yīng).ObjectAnimator objectAnimator = ObjectAnimator.ofInt(new WrapperView(v), "width", 300); objectAnimator.setDuration(2000); objectAnimator.start();
實(shí)現(xiàn)包裝:
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時(shí)的動(dòng)畫
-
XML方式
android:animateLayoutChanges="true"
該種方式只會(huì)使用系統(tǒng)默認(rèn)的動(dòng)畫,用戶不能定制 -
Java
AlphaAnimation alphaAnimation = new AlphaAnimation(0, 1); alphaAnimation.setDuration(2000); LayoutAnimationController controller = new LayoutAnimationController(alphaAnimation, 0.5f); controller.setOrder(LayoutAnimationController.ORDER_NORMAL);//包括三種,正常,隨機(jī),反序 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.+上面按鈕等組件默認(rèn)的動(dòng)畫效果
-
Activity間的過渡動(dòng)畫
在Android5.0之前,Activity之間的動(dòng)畫是通過函數(shù)
overridePendingTransition(Android.R.anim.fade_in, android.R.anim.fade_out);
實(shí)現(xiàn)的,但是他只是單獨(dú)作用在每一Activity之上,并沒有產(chǎn)生協(xié)同作用.
在Android5.0之后,有了新的方式來實(shí)現(xiàn)兩個(gè)Activity之間的過渡Intent intent = new Intent(this, AnimTestActivity.class); startActivity(intent,ActivityOptions.makeSceneTransitionAnimation( this, v, "robot").toBundle());
在兩個(gè)Activity上都存在一個(gè)包含屬性
android:transitionName="robot"
的控件,比如類似下面的格式.
<TextView android:id="@+id/activityBtn" android:transitionName="robot" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Activity效果" />
當(dāng)然,也可以同時(shí)共享多個(gè)View.
ActivityOptions options = ctivityOptions.makeSceneTransitionAnimation(this, Pair.create(view1, "agreedName1"), Pair.create(view2, "agreedName2"));
-
待補(bǔ)充...