您好,登錄后才能下訂單哦!
本篇內容介紹了“如何實現Material Component動畫基礎”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
物理動畫,顧名思義是基于物理學定律基礎的動畫效果,它實際上參考的就是彈簧的形變過程,即胡克定律,這種動畫類型,通常被稱為Spring Animation。官網上其實在很不起眼的小角落有一篇非常詳細的文檔,如下所示。
https://developer.android.com/guide/topics/graphics/spring-animation#add-support-library
對于Spring Animation來說,通常有兩種常用的場景,即彈性和阻尼,彈性定義的是物體恢復到某個狀態下的非線性過程,而阻尼,則定義的是拖動物體的非線性阻力。
關于Spring的設計定義,大家可以參考下這篇文章 https://zhuanlan.zhihu.com/p/127266926。
首先,我們來看下彈性的實現。首先,需要引入Google的Spring實現庫,代碼如下所示。
api 'androidx.dynamicanimation:dynamicanimation:1.0.0'
要使用Spring Animation其實非常簡單,定義SpringAnimation即可,甚至不用設置參數,下面就通過一個最簡單的示例,來演示下如何使用Spring Animation,代碼如下所示。
class MainActivity : AppCompatActivity() {
var offsetX: Float = 0f
var offsetY: Float = 0f
@SuppressLint("ClickableViewAccessibility")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
test.setOnTouchListener { v, event ->
when (event.action) {
MotionEvent.ACTION_DOWN -> {
offsetX = event.rawX
offsetY = event.rawY
}
MotionEvent.ACTION_MOVE -> {
test.translationX = event.rawX - offsetX
test.translationY = event.rawY - offsetY
}
MotionEvent.ACTION_UP -> {
SpringAnimation(test, DynamicAnimation.TRANSLATION_Y).apply {
spring = SpringForce().apply {
// dampingRatio = DAMPING_RATIO_NO_BOUNCY
// stiffness = SpringForce.STIFFNESS_VERY_LOW
}
animateToFinalPosition(0f)
}
SpringAnimation(test, DynamicAnimation.TRANSLATION_X).apply {
spring = SpringForce().apply {
// dampingRatio = DAMPING_RATIO_NO_BOUNCY
// stiffness = SpringForce.STIFFNESS_VERY_LOW
}
animateToFinalPosition(0f)
}
}
}
true
}
}
}
上面的代碼定義了一個可以拖動并改變位置的View,當執行ACTION_UP的時候,就會執行定義的SpringAnimation,SpringAnimation需要幾個參數,即TargetView、執行動畫的屬性、以及最終的屬性值,而動畫,則可以通過調用start(),或調用animateToFinalPosition()方法來啟動,它們的區別就是是否設置了finalPosition,效果如圖所示。
很簡單的幾行代碼就實現了彈性的效果。
基于Spring特性的動畫可以更改屏幕上的View的實際屬性,從而為View添加動畫效果。系統中支持了下面這些屬性。
實際上與屬性動畫的默認屬性值基本是一致的,其本質,也是借助了屬性動畫來實現Spring效果。
與屬性動畫一樣,Spring Animation同樣可以監聽其動畫的生命周期,系統提供了OnAnimationUpdateListener和OnAnimationEndListener,來監聽動畫。
通過addUpdateListener來設置,代碼如下所示。
anim.addUpdateListener { _, value, _ -> anim.animateToFinalPosition(value) }
與之對應的,系統提供了removeUpdateListener() 和 removeEndListener()方法來移除監聽。
對應一個彈性系統來說,SpringForce是描述該彈性系統的各種參數的封裝。
SpringForce:定義動畫具有的彈簧特征。其中有四個關鍵的參數:
finalPosition:靜止位置。
stiffness:即彈簧常數,物體的彈性系數。
dampingRatio:阻尼比。描述系統擾動后的振蕩衰減過程。
velocity:運動的初速度。
在這四個參數中,finalPosition用于描述動畫最終停止的位置,而velocity則是描述物體運動的初速度,默認情況下,velocity為0,系統提供了setStartVelocity()方法來改變這個初速度,在大部分情況下,我們都不用修改。
剩下兩個屬性stiffness和dampingRatio,則是Spring Animation的核心配置參數。
阻尼比用于描述彈簧振動逐漸衰減的狀況。通過使用阻尼比,可以定義振動從一次彈跳到下一次彈跳所衰減的速度有多快。
一般來說,首先需要調用getSpring()方法來獲取當前的參數,再通過調用setDampingRatio()方法設置要增加到彈簧上的阻尼比。
系統同時也定義了一些常用的dampingRatio。
DAMPING_RATIO_HIGH_BOUNCY效果:
DAMPING_RATIO_MEDIUM_BOUNCY效果:
DAMPING_RATIO_LOW_BOUNCY效果:
DAMPING_RATIO_NO_BOUNCY效果:
相信大家通過GIF,就能很快明白其含義了。
剛度定義了用于衡量彈簧強度的彈簧常量。通過setStiffness()方法來設置剛度值,類似的,系統也定義了一些默認的剛度常量。
STIFFNESS_HIGH效果:
STIFFNESS_MEDIUM效果:
STIFFNESS_LOW效果:
STIFFNESS_VERY_LOW效果:
物理動畫的另一個常用場景,則是創建拉動的阻尼效果,相比生硬的控制,通過阻尼設置拉動效果,動畫會更加符合物理定律,讓動畫更加優雅。不過,設置阻尼動畫,其實并不需要Google的Spring Animation,我們通過一個函數,即可完成阻尼效果的實現,其實,所謂的阻尼,即在拉動過程中,將線性的拉動距離,通過一個函數變換,轉換為非線性的遞減函數,遞減函數的斜率,即為阻尼的力度,這樣的函數有很多,這里介紹其中一種。
阻尼效果
private fun doDamping(value: Float): Float {
return if (value < 0)
-sqrt((100f * abs(value)).toDouble()).toFloat()
else
sqrt((100f * value).toDouble()).toFloat()
}
通過這樣一個變換,就可以實現阻尼效果。
例如我們將第一個場景中的拉動效果來增加阻尼效果,只需要在Move的過程中,不斷改變偏移量即可,代碼如下所示。
MotionEvent.ACTION_MOVE -> {
test.translationX = doDamping(event.rawX - offsetX)
test.translationY = doDamping(event.rawY - offsetY)
}
那么借助這樣一個函數,就很方便的實現了變換效果,如圖所示。
除了前面的示例外,這里還給大家提供了一些其它屬性的使用示例。
設置ROTATION屬性,代碼如下所示。
test.setOnTouchListener { view, event ->
val centerX = view.width / 2.0
val centerY = view.height / 2.0
val x = event.x
val y = event.y
fun updateRotation() {
currentRotation = view.rotation + Math.toDegrees(atan2(x - centerX, centerY - y)).toFloat()
}
when (event.actionMasked) {
MotionEvent.ACTION_DOWN -> updateRotation()
MotionEvent.ACTION_MOVE -> {
previousRotation = currentRotation
updateRotation()
val angle = currentRotation - previousRotation
view.rotation += angle
}
MotionEvent.ACTION_UP -> SpringAnimation(
test,
DynamicAnimation.ROTATION
).animateToFinalPosition(0f)
}
true
}
效果如下所示。
設置SCALE_X和SCALE_Y屬性,代碼如下所示。
scaleGestureDetector = ScaleGestureDetector(this,
object : ScaleGestureDetector.SimpleOnScaleGestureListener() {
override fun onScale(detector: ScaleGestureDetector): Boolean {
scaleFactor *= detector.scaleFactor
test.scaleX *= scaleFactor
test.scaleY *= scaleFactor
return true
}
})
test.setOnTouchListener { _, event ->
if (event.action == MotionEvent.ACTION_UP) {
SpringAnimation(test, DynamicAnimation.SCALE_X).animateToFinalPosition(1f)
SpringAnimation(test, DynamicAnimation.SCALE_Y).animateToFinalPosition(1f)
} else {
scaleGestureDetector.onTouchEvent(event)
}
true
}
效果如圖所示。
設置TRANSLATION_Y來實現View出現的動畫效果,代碼如下所示。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
test.translationY = 1600f
SpringAnimation(test, SpringAnimation.TRANSLATION_Y, 0f).apply {
spring.stiffness = SpringForce.STIFFNESS_VERY_LOW
spring.dampingRatio = SpringForce.DAMPING_RATIO_LOW_BOUNCY
setStartVelocity(-2000f)
start()
}
}
效果如下所示。
在KTX中,Google還基于Spring Animation,提供了一些拓展函數,來進一步簡化Spring的使用,地址如下所示。
implementation "androidx.dynamicanimation:dynamicanimation-ktx:1.0.0-alpha03"
“如何實現Material Component動畫基礎”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。