為什么要引入屬性動畫
- 逐幀動畫主要是用來實現(xiàn)動畫的静袖,
而補間動畫才能實現(xiàn)控件的漸入漸出、移動俊扭、旋轉和縮放效果队橙;
屬性動畫是在Android 3.0時才引入的,之前是沒有的萨惑。
既然補間動畫和逐幀動畫已經(jīng)很全了捐康,為什么還要引入屬性動畫呢?
假設:如何利用補間動畫來將一個控件的背景色在1分鐘內從綠色變?yōu)榧t色庸蔼?
這個效果是沒辦法僅僅通過改變控件的漸入漸出解总、移動、旋轉和縮放來實現(xiàn)的姐仅,
但卻可以通過屬性動畫完美地實現(xiàn)花枫。
這就是要引入屬性動畫的第一個原因:
屬性動畫是為了彌補視圖動畫的不足而設計的刻盐,
能夠實現(xiàn)補間動畫無法實現(xiàn)的功能。補間動畫
和逐幀動畫
統(tǒng)稱為視圖動畫
乌昔,
從字面意思
中可以看出隙疚,
這兩個動畫
只能對派生自View類
的控件實例
起作用壤追;
而屬性動畫
磕道,
從名字中
可看出它是作用于控件屬性
的。
正因為屬性動畫
能夠只針對控件
的某一個屬性
來做動畫行冰,
所以造就了它能單獨
改變控件某一個屬性的值
溺蕉,比如顏色
。
這就是屬性動畫
能實現(xiàn)補間動畫
無法實現(xiàn)的功能的最重要
的原因悼做。視圖動畫僅能對指定的View實例控件做動畫疯特,
而屬性動畫
是通過改變控件
的某一屬性值
來做動畫的。
我們準備一個button和一個TextView肛走,
首先給TextView控件添加了單擊響應事件漓雅,
當單擊該TextView時,會彈出Toast提示朽色;
然后邻吞,
在單擊按鈕的時候,TextView控件開始向右下角移動葫男。
從結果中可以看出抱冷,
在移動前,單擊TextView控件是可以彈出Toast提示的梢褐;
而在移動后旺遮,單擊TextView控件則沒有響應,
相反盈咳,單擊TextView控件原來所在的區(qū)域會彈出Toast提示耿眉。
這就說明補間動畫雖然能對控件做動畫,
但是并沒有改變控件內部的屬性值鱼响。
視圖動畫與屬性動畫的區(qū)別
-
1.操作對象
視圖動畫只能操作視圖對象(各種組件鸣剪、各種View、ViewGroup)热押;
-
屬性動畫可以操作任意對象(除了View西傀,還可以是基本類型數(shù)據(jù)等);
- 動畫系統(tǒng)本質:給定一個初始值和一個終止值桶癣,
令對象從初始值到終止值做一個平滑的變化(變化過程可以變速拥褂、勻速、不規(guī)則速度)
- 動畫系統(tǒng)本質:給定一個初始值和一個終止值桶癣,
-
- 屬性的改變
- 視圖動畫沒有對屬性做真正的改變牙寞,只是做出動畫效果而已饺鹃;
(位移動畫后View的響應區(qū)沒有改變莫秆;縮放動畫結束后獲取View的長寬其值亦沒有改變) - 屬性動畫能夠做真正的屬性改變;
- 視圖動畫實現(xiàn)的效果悔详,屬性動畫都能實現(xiàn)镊屎;
從直觀上來看,視圖動畫與屬性動畫有如下三點不同茄螃。
(1)引入時間不同:View Animation是在API Level 1時引入的缝驳;而Property Animation是在API Level 11時引入的,即從Android 3.0才開始有與Property Animation相關的API归苍。
(2)所在包名不同:View Animation API在android.view.animation 包中用狱,而Property Animation API在android.animation包中。
(3)動畫類的命名不同:View Animation中的動畫類命名都是XXXXAnimation拼弃,而Property Animation中的動畫類命名都是XXXXAnimator夏伊。
動畫屬性
1 時長
2 時間插值器
3 重復次數(shù)以及重復模式
4 動畫集
-
5 延遲
- 屬性動畫干的事情,就是在一段時間內讓屬性值不斷地做變化吻氧;
(變化過程可以變速溺忧、勻速、不規(guī)則速度)盯孙,
一系列的屬性改變即成就了一個動畫鲁森;
- 屬性動畫干的事情,就是在一段時間內讓屬性值不斷地做變化吻氧;
屬性動畫相關的類,
都被定義在了android.animation包當中镀梭,
包中有一個抽象類Animator刀森,
它包含了以上提到的五個屬性的相關方法;動畫對象都是可悲開始报账、可被暫停研底、可被監(jiān)聽的;
-
Animator的子類
- ValueAnimator 控制值的變化透罢;
屬性動畫干的事情榜晦,就是在一段時間內讓屬性值
不斷地做變化;
ValueAnimator 就是令這個屬性值
不斷地做變化的驅動羽圃;
- ValueAnimator 控制值的變化透罢;
ValueAnimator
在上篇博客Android動畫基礎詳析 | 概述乾胶、逐幀動畫、視圖動畫(附諸多實際運行效果動圖)的基礎上我們新建一個property包和一個PropertyActivity:
activity_property.xml:
<?xml version="1.0" encoding="utf-8"?>
<RealativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".property.PropertyActivity">
<Button
android:id="@+id/btnValueAnimator"
android:text="Go"
android:onClick="onClick"
android:layout_width = "match_parent"
android:layout_height= "wrap_content"/>
</RealativeLayout>
PropertyActivity.java:
public class PropertyActivity extends AppCompatActivity {
private static final String TAG = "PropertyActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_property);
}
public void onClick(View view){
switch (view.getId()){
case R.id.btnValueAnimator:
ValueAnimator valueAnimator = ValueAnimator.ofInt(0,100);//ValueAnimator的正態(tài)方法ofInt朽寞,驅動整型數(shù)值
valueAnimator.setDuration(100);//設置時長
//設置屬性刷新監(jiān)聽器
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
//通過animation對象可以獲取諸多動畫相關屬性
//獲取當前的動畫變化完成度识窿,范圍 0.0 - 1.0,0.0表示剛開始脑融, 1.0表示完成
float animatedFracion = animation.getAnimatedFraction();
//獲取當前狀態(tài)基于正態(tài)方法的始末參數(shù)間的插值喻频,強制轉換的類型就看正態(tài)方法的數(shù)據(jù)類型;
int animatedValue = (int)animation.getAnimatedValue();
//打印這兩個參數(shù)肘迎,其中%.3f即保留小數(shù)點后三位
Log.d(TAG, "onAnimationUpdate: "
+ String.format("%.3f %d", animatedFracion,animatedValue));
}
});
valueAnimator.start();//開始動畫
break;
}
}
}
運行代碼:
第一列數(shù)據(jù)是動畫變化完成度甥温,第二列數(shù)據(jù)是插值锻煌,
我們可以看到打印出來的值并不是線性的,???
因為ValueAnimator默認的插值器不是勻速的姻蚓;???
下面給ValueAnimator設置插值器即可:
...
valueAnimator.setDuration(100);//設置時長
valueAnimator.setInterpolator(new LinearInterpolator());//設置插值器
//設置屬性刷新監(jiān)聽器
...
ValueAnimator的簡單使用案例
-
ValueAnimator.ofFloat(0f宋梧,400f,50f狰挡,300f)
構造了一個比較復雜的動畫漸變捂龄,
值從0變到400,再回到50圆兵,最后變成300跺讯,
通過getAnimatedValue()函數(shù)來獲取當前運動點的值,
在得到當前運動點的值以后殉农,
通過layout()函數(shù)將TextView移動到指定位置即可
ValueAnimator只負責對指定值區(qū)間進行動畫運算;
我們需要對運算過程進行監(jiān)聽局荚,然后自己對控件執(zhí)行動畫操作超凳。ofInt()與ofFloat()的唯一區(qū)別就是傳入的數(shù)值類型不一樣,ofInt()函數(shù)需要傳入Integer類型的參數(shù)耀态,而ofFloat()函數(shù)則需要傳入Float類型的參數(shù)轮傍。
它們的參數(shù)類型都是可變長參數(shù),所以我們可以傳入任何數(shù)量的值首装;
傳進去的值列表就表示動畫時的變化范圍创夜,
比如ofInt(2,90仙逻,45)就表示從數(shù)字2變化到數(shù)字90再變化到數(shù)字45驰吓,
所以我們傳進去的數(shù)字越多,
動畫變化就越復雜系奉。
-
為什么通過getAnimatedValue()函數(shù)來獲取當前valueAnimator產(chǎn)生的值的時候檬贰,需要轉換成Integer/Float類型?
getAnimatedValue()函數(shù)的聲明
Object getAnimatedValue();
它返回的是Object原始類型缺亮,
那我們怎么知道要將它轉換成什么類型呢翁涤?
注意,
如果我們在設定動畫初始值時使用的是ofFloat()
函數(shù)萌踱,
則每個值的類型必定是Float
類型葵礼,
我們獲取到的類型也必然是Float
類型。
同樣并鸵,如果我們使用ofInt()
函數(shù)設定動畫初始值鸳粉,
那么通過getAnimatedValue()
函數(shù)獲取到的值
就應該轉換為Integer
類型。
常用函數(shù)匯總
setRepeatCount(int value)函數(shù)用于設置動畫循環(huán)次數(shù)能真,
設置為0表示不循環(huán)赁严,
設置為ValueAnimation.INFINITE表示無限循環(huán)扰柠。cancel()函數(shù)用于取消動畫。
setRepeatMode(int value)函數(shù)用于設置循環(huán)模式疼约,
當取值為ValueAnimation.RESTART時卤档,表示正序重新開始;
當取值為ValueAnimation.REVERSE時程剥,表示倒序重新開始劝枣。注意:重復次數(shù)為INFINITE(無限循環(huán))的動畫,
當Activity結束的時候织鲸,必須調用cancel()函數(shù)取消動畫舔腾,
否則動畫將無限循環(huán),從而導致View無法釋放搂擦,
進一步導致整個Activity無法釋放稳诚,最終引起內存泄漏。
監(jiān)聽器
-
animator.addUpdateListener瀑踢,用于監(jiān)聽動畫過程中值的實時變化扳还。
其實在ValueAnimator中,共有兩個監(jiān)聽器:
- 當動畫開始時橱夭,會通過onAnimationStart()函數(shù)返回氨距;
在每一次重復時,都會調用一次onAnimationRepeat()函數(shù)棘劣;
在調用cancel()函數(shù)取消動畫時俏让,會通過onAnimationCancel()函數(shù)返回;
在動畫終止時茬暇,會調用onAnimationEnd()函數(shù)通知用戶首昔;
移除監(jiān)聽器
removeListener(AnimatorListener listener)函數(shù)
用于在Animator中移除指定的監(jiān)聽器;removeAllListeners()函數(shù)
用于移除Animator中所有的監(jiān)聽器而钞。
其他函數(shù)
- setStartDelay(long startDelay)函數(shù)非常容易理解沙廉,就是設置延時多久后動畫開始。
- clone()函數(shù)就是復制出來一個完全一樣的新的ValueAnimator實例臼节,
對原來的ValueAnimator是怎么處理的撬陵,
在這個新的實例中也采用相同的處理方式;
至此网缝,補充一個實戰(zhàn):
自定義View實戰(zhàn) | 彈跳的loading效果
一個主要是由ValueAnimator實現(xiàn)的自定義View
-
接下來是屬性動畫的其他補充內容了巨税,
鑒于篇幅有限,這里另開幾篇博客——
粉臊,敬請點擊此處前往惠讀~ -
《自定義View |
插值器Interpolator與Evaluator詳解與自定義運用
》 -
自定義View | ofObject詳解與實戰(zhàn)(ValueAnimator進階)
- 本文內容參考自 慕課網(wǎng). 就業(yè)班
- 以及《Android自定義控件開發(fā)入門與實戰(zhàn)》