轉載請标明出處:http://blog.csdn.net/zhaoyanjun6/article/details/118709616
本文出自【趙彥軍的部落格】
文章目錄
- ObjectAnimator
- 實戰-心跳動畫
- 參考資料
ObjectAnimator
public final class ObjectAnimator extends ValueAnimator {
...
}
ObjectAnimator
繼承
ValueAnimator
, 是以
ObjectAnimator
擁有
ValueAnimator
一切特性。
相比于
ValueAnimator
,
ObjectAnimator
可能才是我們最常接觸到的類,因為
ValueAnimator
隻不過是對值進行了一個平滑的動畫過渡,但我們實際使用到這種功能的場景好像并不多。而
ObjectAnimator
則就不同了,它是可以直接對任意對象的任意屬性進行動畫操作的,比如說
View
的
alpha
屬性。
不過雖說
ObjectAnimator
會更加常用一些,但是它其實是繼承自
ValueAnimator
的,底層的動畫實作機制也是基于ValueAnimator來完成的,是以
ValueAnimator
仍然是整個屬性動畫當中最核心的一個類。那麼既然是繼承關系,說明
ValueAnimator
中可以使用的方法在
ObjectAnimator
中也是可以正常使用的,它們的用法也非常類似,這裡如果我們想要将一個
TextView
在5秒中内從正常變換成全透明,再從全透明變換成正常,就可以這樣寫:
ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "alpha", 1f, 0f, 1f);
animator.setDuration(5000);
animator.start();
可以看到,我們還是調用了
ofFloat()
方法來去建立一個
ObjectAnimator
的執行個體,隻不過
ofFloat()
方法當中接收的參數有點變化了。這裡第一個參數要求傳入一個
object
對象,我們想要對哪個對象進行動畫操作就傳入什麼,這裡我傳入了一個
textview
。第二個參數是想要對該對象的哪個屬性進行動畫操作,由于我們想要改變
TextView
的不透明度,是以這裡傳入
"alpha"
。後面的參數就是不固定長度了,想要完成什麼樣的動畫就傳入什麼值,這裡傳入的值就表示将
TextView
從正常變換成全透明,再從全透明變換成正常。之後調用
setDuration()
方法來設定動畫的時長,然後調用
start()
方法啟動動畫,效果如下圖所示:

學會了這一個用法之後,其它的用法我們就可以舉一反三了,那比如說我們想要将
TextView
進行一次
360度
的旋轉,就可以這樣寫:
ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "rotation", 0f, 360f);
animator.setDuration(5000);
animator.start();
可以看到,這裡我們将第二個參數改成了
"rotation"
,然後将動畫的初始值和結束值分别設定成
0和360
,現在運作一下代碼,效果如下圖所示:
那麼如果想要将TextView先向左移出螢幕,然後再移動回來,就可以這樣寫:
float curTranslationX = textview.getTranslationX();
ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "translationX", curTranslationX, -500f, curTranslationX);
animator.setDuration(5000);
animator.start();
這裡我們先是調用了
TextView
的
getTranslationX()
方法來擷取到目前
TextView的translationX
的位置,然後
ofFloat()
方法的第二個參數傳入
"translationX"
,緊接着後面三個參數用于告訴系統
TextView
應該怎麼移動,現在運作一下代碼,效果如下圖所示:
然後我們還可以
TextView
進行縮放操作,比如說将
TextView
在垂直方向上放大3倍再還原,就可以這樣寫:
ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "scaleY", 1f, 3f, 1f);
animator.setDuration(5000);
animator.start();
這裡将ofFloat()方法的第二個參數改成了"scaleY",表示在垂直方向上進行縮放,現在重新運作一下程式,效果如下圖所示:
到目前為止,
ObjectAnimator
的用法還算是相當簡單吧,但是我相信肯定會有不少朋友現在心裡都有同樣一個疑問,就是
ofFloat()
方法的第二個參數到底可以傳哪些值呢?
目前我們使用過了
alpha
、
rotation
、
translationX
和
scaleY
這幾個值,分别可以完成淡入淡出、旋轉、水準移動、垂直縮放這幾種動畫,那麼還有哪些值是可以使用的呢?
其實這個問題的答案非常玄乎,就是我們可以傳入任意的值到
ofFloat()
方法的第二個參數當中。任意的值?相信這很出乎大家的意料吧,但事實就是如此。因為
ObjectAnimator
在設計的時候就沒有針對于
View
來進行設計,而是針對于任意對象的,它所負責的工作就是不斷地向某個對象中的某個屬性進行指派,然後對象根據屬性值的改變再來決定如何展現出來。
那麼比如說我們調用下面這樣一段代碼:
其實這段代碼的意思就是
ObjectAnimator
會幫我們不斷地改變
textview
對象中
alpha
屬性的值,從1f變化到0f。然後
textview
對象需要根據
alpha
屬性值的改變來不斷重新整理界面的顯示,進而讓使用者可以看出淡入淡出的動畫效果。
那麼
textview
對象中是不是有
alpha
屬性這個值呢?
沒有,不僅
textview
沒有這個屬性,連它所有的父類也是沒有這個屬性的!
這就奇怪了,
textview
當中并沒有alpha這個屬性,
ObjectAnimator
是如何進行操作的呢?其實
ObjectAnimator
内部的工作機制并不是直接對我們傳入的屬性名進行操作的,而是會去尋找這個屬性名對應的
get和set
方法,是以alpha屬性所對應的
get和set
方法應該就是:
public void setAlpha(float value);
public float getAlpha();
那麼
textview
對象中是否有這兩個方法呢?确實有,并且這兩個方法是由
View
對象提供的,也就是說不僅
TextView
可以使用這個屬性來進行淡入淡出動畫操作,任何繼承自
View
的對象都可以的。
既然
alpha
是這個樣子,相信大家一定已經明白了,前面我們所用的所有屬性都是這個工作原理,那麼View當中一定也存在着
setRotation()
、
getRotation()
、
setTranslationX()
、
getTranslationX()
、
setScaleY()
、
getScaleY()
這些方法,不信的話你可以到View當中去找一下。
實戰-心跳動畫
先上效果圖:
自定義 View
/**
* @author : zhaoyanjun
* @time : 2021/7/13
* @desc :
*/
class MyView(context: Context?, attrs: AttributeSet?) : View(context, attrs) {
private var radius = 10f //圓的半徑
set(value) {
field = value
invalidate()
}
private val paint = Paint()
init {
paint.color = Color.BLUE
paint.textSize = 8f
paint.isAntiAlias = true
paint.style = Paint.Style.FILL
}
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
//繪制圓
canvas?.drawCircle((width / 2).toFloat(), (height / 2).toFloat(), radius, paint)
}
}
有一點很重要的是,
radius
的 set 方法中需要調用
invalidate()
方法,才能夠重新整理
view
我們再看執行動畫的部分
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var myView: MyView = findViewById(R.id.myView)
//通過動畫,不斷的改變 radius 的值
var objectAnimator =
ObjectAnimator.ofFloat(myView, "radius", 200f, 500f, 200f)
objectAnimator.duration = 600
objectAnimator.interpolator = LinearInterpolator()
objectAnimator.repeatCount = 20 //執行20次
objectAnimator.start()
}
}
參考資料
- Android屬性動畫完全解析(上),初識屬性動畫的基本用法