Android三種動畫詳解
前言
2018-08-09 09:57:04
自尊,自律,自強,自愛。--Power
一直以來自己對Android的動畫一知半解,所以決定寫這篇文章來詳細系統(tǒng)的學(xué)習(xí)Android的三種動畫,即
- View Animation(視圖動畫)
- Drawable Animation(幀動畫)
- Property Animation(屬性動畫)
正文
1.View Animation(視圖動畫)
1.1 View動畫的概述及種類
視圖動畫的作用對象是View,支持四種動畫效果,分別是平移動畫,縮放動畫,旋轉(zhuǎn)動畫,透明度動畫。譬如,我們可以對TextView設(shè)置其文本的移動,旋轉(zhuǎn),縮放,透明。
視圖動畫可以通過XML或通過代碼動態(tài)創(chuàng)建,對于視圖動畫建議使用XML文件定義,因為它具有更高的可讀性,可重用性。
下面我們來分別看一下View動畫的四種效果:
-
平移動畫(TranslateAnimation)
translate_ani-w140 -
縮放動畫(ScaleAnimation)
scale_ani-w140 -
旋轉(zhuǎn)動畫(RotateAnimation)
rotate_ani-w140 -
透明度動畫(AlphaAnimation)
alhpa_ani-w140
view動畫的四種變換我們通過效果圖已基本了解,下面我們通過表格系統(tǒng)的了解一下:
| 名稱 | 標(biāo)簽 | 子類 | 效果 |
|---|---|---|---|
| 平移動畫 | < translate > | TranslateAnimation | 移動View |
| 縮放動畫 | < scale > | ScaleAnimation | 方法或縮小View |
| 旋轉(zhuǎn)動畫 | < rotate > | RotateAnimation | 旋轉(zhuǎn)view |
| 透明度動畫 | < alpha > | AlphaAnimation | 改變View的透明度 |
要使用View動畫,首先要創(chuàng)建XML文件,我們需要在res下新建anim文件夾,接著在anim下創(chuàng)建animation resource file的xml文件,我們舉例為view_anim.xml
我們通過xml文件來了解它們各自的語法:
<?xml version="1.0" encoding="utf-8"?>
<set
xmlns:android="http://schemas.android.com/apk/res/android">
<!--平移動畫標(biāo)簽-->
<translate
android:fromXDelta="0%p"
android:toXDelta="20%p"
android:fromYDelta="0%p"
android:toYDelta="20%p"
android:duration="4000"/>
<!--縮放動畫標(biāo)簽-->
<scale
android:fromXScale="1.0"
android:toXScale="0.2"
android:fromYScale="1.0"
android:toYScale="0.2"
android:pivotX="50%"
android:pivotY="50%"
android:duration="4000"/>
<!--旋轉(zhuǎn)動畫標(biāo)簽-->
<rotate
android:fromDegrees="0"
android:toDegrees="360"
android:pivotX="50%"
android:pivotY="50%"
android:duration="4000"/>
<!--透明度動畫標(biāo)簽-->
<alpha
android:fromAlpha="1.0"
android:toAlpha="0.2"
android:duration="4000"/>
</set>
從上面的代碼我們知道,View動畫既可以是單個動畫,也可以有一系列動畫組成。
這是因為View動畫的四種種類分別對應(yīng)著Animation的四個子類(TranslateAnimation,ScaleAnimation,RotateAnimation,AlphaAnimation),除了以上四個子類它還有一個AnimationSet類,對應(yīng)xml標(biāo)簽為<set>,它是一個容器,可以包含若干個動畫,并且內(nèi)部也可以繼續(xù)嵌套<set>集合的。
我們在activity對TextView設(shè)置動畫:
/**
* @author power
* @date 2018-08-08 20:28:58
* @description: MainActivity
*/
public class MainActivity extends AppCompatActivity {
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.textview);
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Animation animation = AnimationUtils.loadAnimation(MainActivity.this,R.anim.viewanimation);
textView.startAnimation(animation);
}
});
}
}
我們來看下動畫集合的運行效果:

1.2 View動畫的屬性詳解
-
Animation屬性詳解:
xml屬性 java方法 解釋 android:duration setDuration(long) 動畫持續(xù)時間,毫秒為單位 android:ShareInterpolator setInterpolator(Interpolator) 設(shè)定插值器(指定的動畫效果,譬如回彈等) android:fillAfter setFillAfter(boolean) 控件動畫結(jié)束時是否保持動畫最后的狀態(tài) android:fillBefore setFillBefore(boolean) 控件動畫結(jié)束時是否還原到開始動畫前的狀態(tài) android:repeatMode setRepeatMode(int) 重復(fù)類型有兩個值,reverse表示倒序回放,restart表示從頭播放 android:startOffset setStartOffset(long)<span class="Apple-tab-span" style="white-space:pre"></span> 調(diào)用start函數(shù)之后等待開始運行的時間,單位為毫秒 -
TranslateAnimation屬性詳解:
xml屬性 java方法 解釋 android:fromXDelta TranslateAnimation(float fromXDelta, …) 起始點X軸坐標(biāo),數(shù)值,百分比,百分比p,注① android:fromYDelta TranslateAnimation(…, float fromYDelta, …) 起始點Y軸從標(biāo),同上規(guī)律 android:toXDelta TranslateAnimation(…, float toXDelta, …) 結(jié)束點X軸坐標(biāo),同上規(guī)律 android:toYDelta TranslateAnimation(…, float toYDelta) 結(jié)束點Y軸坐標(biāo),同上規(guī)律 注①: 數(shù)值、百分?jǐn)?shù)、百分?jǐn)?shù)p,譬如50表示以當(dāng)前View左上角坐標(biāo)加50px為初始點、50%表示以當(dāng)前View的左上角加上當(dāng)前View寬高的50%做為初始點、50%p表示以當(dāng)前View的左上角加上父控件寬高的50%做為初始點
-
ScaleAnimation屬性詳解:
xml屬性 java方法 解釋 android:fromXScale ScaleAnimation(float fromX, …) 初始X軸縮放比例,1.0表示無變化 android:toXScale ScaleAnimation(…, float toX, …) 結(jié)束X軸縮放比例 android:fromYScale ScaleAnimation(…, float fromY, …) 初始Y軸縮放比例 android:toYScale ScaleAnimation(…, float toY, …) 結(jié)束Y軸縮放比例 android:pivotX ScaleAnimation(…, float pivotX, …) 縮放起點X軸坐標(biāo),數(shù)值,百分比,百分比p,注① android:pivotY ScaleAnimation(…, float pivotY) 縮放起點Y軸坐標(biāo),同上規(guī)律 -
RotateAnimation屬性詳解:
xml屬性 Java方法 解釋 android:fromDegrees RotateAnimation(float fromDegrees, …) 旋轉(zhuǎn)開始角度,正代表順時針度數(shù),負代表逆時針度數(shù) android:toDegrees RotateAnimation(…, float toDegrees, …) 旋轉(zhuǎn)結(jié)束角度,正代表順時針度數(shù),負代表逆時針度數(shù) android:pivotX RotateAnimation(…, float pivotX, …) 縮放起點X坐標(biāo),數(shù)值,百分比,百分比p,注① android:pivotY RotateAnimation(…, float pivotY) 縮放起點Y坐標(biāo),同上規(guī)律 -
AlphaAnimation屬性詳解:
xml屬性 java方法 解釋 android:fromAlpha AlphaAnimation(float fromAlpha, …) 動畫開始的透明度(0.0到1.0,0.0是全透明,1.0是不透明) android:toAlpha AlphaAnimation(…, float toAlpha) 動畫結(jié)束的透明度,同上 AnimationSet屬性詳解:
AnimationSet繼承自Animation,是上面四種的組合容器管理類,沒有自己特有的屬性,他的屬性繼承自Animation,所以特別注意,當(dāng)我們對set標(biāo)簽使用Animation的屬性時會對該標(biāo)簽下的所有子控件都產(chǎn)生影響。譬如我們在set標(biāo)簽下加入duration=“1000”,子控件的duration屬性會失效。
1.3 View動畫的使用方法及注意事項
-
上述的使用方法已經(jīng)非常詳細了,也并沒有什么難以理解的地方,我們只需要創(chuàng)建相應(yīng)的xml文件,然后在activity里startAnimation就可以完成動畫了。當(dāng)然了,Animation類和View操作Animation還有一些如下的實用方法:
Animation類的方法 解釋 reset() 重置Animation的初始化 cancel() 取消Animation動畫 start() 開始Animation動畫 setAnimationListener() 給當(dāng)前Animation設(shè)置動畫監(jiān)聽 hasStarted() 判斷當(dāng)前Animation是否開始 hasEnded() 判斷當(dāng)前Animation是否結(jié)束 ---------------------------- ---------------------------- View類對Animation的操作方法 解釋 startAnimation(Animation animation)<span class="Apple-tab-span" style="white-space:pre"></span> 對當(dāng)前View開始設(shè)置的Animation動畫 clearAnimation() 取消當(dāng)View在執(zhí)行的Animation動畫 -
注意事項
- 特別特別注意:補間動畫執(zhí)行之后并未改變View的真實布局屬性值。切記這一點,譬如我們在Activity中有一個 Button在屏幕上方,我們設(shè)置了平移動畫移動到屏幕下方然后保持動畫最后執(zhí)行狀態(tài)呆在屏幕下方,這時如果點擊屏幕下方動畫執(zhí)行之后的Button是沒 有任何反應(yīng)的,而點擊原來屏幕上方?jīng)]有Button的地方卻響應(yīng)的是點擊Button的事件。
- 在進行動畫的時候,盡量使用dp,因為px會導(dǎo)致適配問題。
1.4 View動畫Interpolator插值器詳解
-
插值器簡介
首先,我們先看一下源碼的解釋:
interpolato
注釋說明:插值器定義了動畫的變化,使一些基礎(chǔ)的動畫如(平移,縮放,旋轉(zhuǎn),透明)可以被加速,減速,重復(fù)等
通過上圖可以看見其實系統(tǒng)提供給我們的各類型插值器都是實現(xiàn)了Interpolator接口,具體如下:java類 xml 描述 AccelerateDecelerateInterpolator @android:anim/accelerate_decelerate_interpolator 動畫始末速率較慢,中間加速 AccelerateInterpolator @android:anim/accelerate_interpolator 動畫開始速率較慢,之后慢慢加速 AnticipateInterpolator @android:anim/anticipate_interpolator 開始的時候從后向前甩 AnticipateOvershootInterpolator @android:anim/anticipate_overshoot_interpolator 類似上面AnticipateInterpolator BounceInterpolator @android:anim/bounce_interpolator 動畫結(jié)束時彈起 CycleInterpolator @android:anim/cycle_interpolator 循環(huán)播放速率改變?yōu)檎仪€ DecelerateInterpolator @android:anim/decelerate_interpolator 動畫開始快然后慢 LinearInterpolator @android:anim/linear_interpolator 動畫勻速改變 OvershootInterpolator @android:anim/overshoot_interpolator 向前彈出一定值之后回到原來位置 -
插值器的使用
插值器的使用比較簡答,如下:<set xmlns:android="http://schemas.android.com/apk/res/android" <!--運動結(jié)束時彈起--> android:interpolator="@android:anim/bounce_interpolator"> <!--平移動畫標(biāo)簽--> <translate android:fromXDelta="0%p" android:toXDelta="20%p" android:fromYDelta="0%p" android:toYDelta="20%p" android:duration="4000"/> <!--縮放動畫標(biāo)簽--> </set>我們看一下設(shè)置插值器后的效果:
interpolato-w140 -
插值器的自定義
當(dāng)系統(tǒng)提供給我們的插值器不能滿足開發(fā)需求時,就需要我們自定義,而插值器的自定義有兩種方式,一種xml實現(xiàn),一種java實現(xiàn)。- xml實現(xiàn)方式
在anim文件下創(chuàng)建xml文件
<?xml version="1.0" encoding="utf-8"?> <accelerateInterpolator xmlns:android="http://schemas.android.com/apk/res/android" android:factor="0.8"> </accelerateInterpolator>通過代碼我們發(fā)現(xiàn),這種方式只能修改現(xiàn)有插值器的一些屬性,但有些插值器不具備修改屬性,那么我們就通過java代碼實現(xiàn)進一步需求
- java代碼實現(xiàn)方式
通過上面的學(xué)習(xí)我們知道,所有的插值器都是繼承自Interpolator接口,它則繼承TimeInterpolator接口,而這個接口定義了float getInterpolation(float input);方法
public class AccelerateDecelerateInterpolator extends BaseInterpolator implements NativeInterpolatorFactory { public float getInterpolation(float input) { return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f; } }public interface TimeInterpolator { /** * Maps a value representing the elapsed fraction of an animation to a value that represents * the interpolated fraction. This interpolated value is then multiplied by the change in * value of an animation to derive the animated value at the current elapsed animation time. * * @param input A value between 0 and 1.0 indicating our current point * in the animation where 0 represents the start and 1.0 represents * the end * @return The interpolation value. This value can be more than 1.0 for * interpolators which overshoot their targets, or less than 0 for * interpolators that undershoot their targets. */ float getInterpolation(float input); } - xml實現(xiàn)方式
我們需要繼承Interpolator接口并實現(xiàn)getInterpolation();,在方法里處理業(yè)務(wù)邏輯即可。
2.Drawable Animation(幀動畫)
2.1幀動畫概述
幀動畫是順序播放一組預(yù)先定義好的圖片,不同于View動畫,系統(tǒng)提供了另外一個類AnimationDrawable來使用幀動畫。
2.2幀動畫的使用
首先我們找一組幀動畫的圖片放入drawable-xhdpi文件夾下,其次在drawable文件夾下創(chuàng)建xml文件,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<animation-list
xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="@drawable/refresh1" android:duration="180"/>
<item android:drawable="@drawable/refresh2" android:duration="180"/>
...
<item android:drawable="@drawable/refresh25" android:duration="180"/>
</animation-list>
view = findViewById(R.id.view);
view.setBackgroundResource(R.drawable.drawable_anim);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AnimationDrawable animationDrawable = (AnimationDrawable) view.getBackground();
animationDrawable.start();
}
});
通過上述代碼,幀動畫已經(jīng)完成了,我們來看下效果圖:

<animation-list> 必須是根節(jié)點,包含一個或者多個<item>元素,屬性有:
android:oneshot true代表只執(zhí)行一次,false循環(huán)執(zhí)行。
<item> 類似一幀的動畫資源。
<item> animation-list的子項,包含屬性如下:
android:drawable 一個frame的Drawable資源。
android:duration 一個frame顯示多長時間。
幀動畫很簡單,但容易引起OOM,我在這里也就不多贅述。
3.Property Animation(屬性動畫)
3.1 未完待續(xù)...





