Android轉(zhuǎn)場動(dòng)畫深入分析探究
早期的轉(zhuǎn)場
最初,兩個(gè)Activity之間的切換的過度動(dòng)畫,都是用overridePendingTransition。它只支持平移、縮放、透明度、旋轉(zhuǎn)四種動(dòng)畫效果。
比如我們寫個(gè)平移跳轉(zhuǎn)動(dòng)畫,實(shí)現(xiàn)是這樣的。首先,我們在資源文件anim下新建兩個(gè)動(dòng)畫資源文件 enter_anim.xml 和 quit_anim.xml,分別表示進(jìn)入和退出的動(dòng)畫。
enter_anim.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500">
<translate
android:fromXDelta="100%p"
android:toXDelta="0" />
</set>
quit_anim.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500">
<translate
android:fromXDelta="0"
android:toXDelta="-100%p" />
</set>
然后在界面跳轉(zhuǎn)的時(shí)候,調(diào)用overridePendingTransition就行啦
startActivity(Intent(this, TestActivity::class.java))
overridePendingTransition(R.anim.enter_anim, R.anim.quit_anim)
Material Design 轉(zhuǎn)場動(dòng)畫
Android 5.0之后使用,具有三種轉(zhuǎn)場動(dòng)畫效果:
- Explode:爆炸式,將視圖移入場景中心或從中移出
- Fade:淡入淡出式,通過更改透明度來添加和移出視圖
- Slide:滑動(dòng)式,從場景的一個(gè)邊緣移入或移出視圖
Materia轉(zhuǎn)場有兩種啟用方式,一種是在theme中設(shè)置 windowActivityTransitions
<style name="Theme.AndroidApp" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<item name="android:windowActivityTransitions">true</item>
</style>
一種是通過代碼開啟
window.requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)
下面,通過一個(gè)簡單的示例,來瞧瞧具體是怎么去使用的
在MainActivity中設(shè)置退出動(dòng)畫,然后通過點(diǎn)擊事件去進(jìn)行跳轉(zhuǎn)到TestActivity
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
window.apply {
requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)
exitTransition = Fade() //退出動(dòng)畫
}
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.go.setOnClickListener {
materialGo()
}
}
private fun materialGo() {
val intent = Intent(this, TestActivity::class.java)
startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this).toBundle())
}
}在TestActivity中設(shè)置進(jìn)入動(dòng)畫,這樣淡入淡出式就完成了
class TestActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
window.run {
requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)
enterTransition = Fade() //進(jìn)入動(dòng)畫
}
super.onCreate(savedInstanceState)
val binding = ActivityTestBinding.inflate(layoutInflater)
setContentView(binding.root)
}
}
共享元素
如下所示,共享元素的效果很有趣,看著就像是圖片從一個(gè)頁面放大到另一個(gè)頁面

共享元素過渡方式有四種
- changeBounds:為目標(biāo)視圖布局邊界的變化添加動(dòng)畫效果
- changeClipBounds:為目標(biāo)視圖裁剪邊界的變化添加動(dòng)畫效果
- changeTransform:為目標(biāo)視圖縮放和旋轉(zhuǎn)方面的變化添加動(dòng)畫效果
- changeImageTransform:為目標(biāo)圖片尺寸和縮放方面的變化添加動(dòng)畫效果
首先需要設(shè)置transitionName,告訴系統(tǒng),哪個(gè)View需要做動(dòng)畫,然后進(jìn)行Activity的跳轉(zhuǎn)
binding.image.setOnClickListener {
binding.image.transitionName = "shared_elements"
val options =
ActivityOptions.makeSceneTransitionAnimation(this, binding.image, "shared_elements")
val intent = Intent(this, TestActivity::class.java)
startActivity(intent, options.toBundle())
}
在目標(biāo)Activity中給View設(shè)置transitionName,也可添加一系列的過渡效果
class TestActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
val transitionSet = TransitionSet().apply {
addTransition(ChangeBounds())
addTransition(ChangeClipBounds())
addTransition(ChangeTransform())
addTransition(ChangeImageTransform())
}
with(window) {
requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)
sharedElementEnterTransition = transitionSet
sharedElementExitTransition = transitionSet
}
super.onCreate(savedInstanceState)
val binding = ActivityTestBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.picture.transitionName = "shared_elements"
}
}如果要使用多個(gè)共享元素,可使用Pair,例如
val options = ActivityOptionsCompat.makeSceneTransitionAnimation(
this, Pair(binding.imageView, "imageView"),
Pair(binding.signature, "signature")
)Material Motion 動(dòng)畫
它提供了四種模式,可以根據(jù)需求靈活選用,分別是:
MaterialContainerTransform
用于包含容器的界面元素之間的過渡,通過將一個(gè)UI元素?zé)o縫轉(zhuǎn)換為另一個(gè)UI元素,在兩個(gè)不同的界面元素之間創(chuàng)造可視化的連接,跟之前共享元素動(dòng)畫最大的不同點(diǎn)在于它可以是一個(gè) ViewGroup,也可以是一個(gè) View。
下面,我們通過一個(gè)簡單的例子來感受一下效果,item是個(gè)LinearLayout,用于點(diǎn)擊跳轉(zhuǎn)。
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
//1.啟用轉(zhuǎn)場動(dòng)畫
window.requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)
setExitSharedElementCallback(MaterialContainerTransformSharedElementCallback())
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
initView()
}
private fun initView() {
//2.設(shè)置transitionName
binding.item.transitionName = "share"
binding.item.setOnClickListener {
//3.進(jìn)行頁面跳轉(zhuǎn)
startActivity(
Intent(this, TestActivity::class.java),
ActivityOptions.makeSceneTransitionAnimation(this, it, "share").toBundle()
)
}
}
}在目標(biāo)Activity中,只顯示了幾行文本,整體用LinearLayout做容器,id為display。
這里為了更加清楚的看到動(dòng)畫的轉(zhuǎn)換過程,我將動(dòng)畫的執(zhí)行時(shí)間duration設(shè)置為2秒,實(shí)際開發(fā)中,不能搞這么久哦。
class TestActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
//1.啟用轉(zhuǎn)場動(dòng)畫
window.requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)
setEnterSharedElementCallback(MaterialContainerTransformSharedElementCallback())
super.onCreate(savedInstanceState)
val binding = ActivityTestBinding.inflate(layoutInflater)
setContentView(binding.root)
//2.設(shè)置transitionName
binding.display.transitionName = "share"
//3.設(shè)置具體的動(dòng)畫
window.sharedElementEnterTransition = MaterialContainerTransform().apply {
addTarget(binding.display)
scrimColor = Color.TRANSPARENT
setAllContainerColors(Color.WHITE)
duration = 2000L
}
window.sharedElementExitTransition = MaterialContainerTransform().apply {
addTarget(binding.display)
scrimColor = Color.TRANSPARENT
setAllContainerColors(Color.WHITE)
duration = 2000L
}
}
}MaterialContainerTransform有兩個(gè)屬性需要注意下:
- scrimColor:用于控制在動(dòng)畫容器后面繪制的半透明陰影的顏色。默認(rèn)情況下,該元素會(huì)設(shè)為 32% 黑色。這里將其設(shè)為透明,這意味著不會(huì)繪制任何紗罩。
- setAllContainerColors:在兩個(gè)視圖之間添加動(dòng)畫時(shí),它會(huì)在畫布上繪制 3 個(gè)容器: 后臺(tái)容器 ,起始視圖的容器和結(jié)束視圖的容器。對(duì)于這 3 個(gè)容器,我們都可以為其填充顏色,并將其默認(rèn)設(shè)為透明。如果您的起始視圖或結(jié)束視圖本身沒有繪制背景,導(dǎo)致在動(dòng)畫播放期間其他元素顯示在其下層,那么設(shè)置這些背景填充顏色可能會(huì)很有用。我們可以使用 setAllContainerColors 來統(tǒng)一顏色,確保我們不會(huì)遇到任何視覺問題。

Shared axis
用于具有空間或?qū)Ш疥P(guān)系的界面元素之間的過渡,讓元素在轉(zhuǎn)換時(shí)共用 x 軸、y 軸或 z 軸,用以強(qiáng)調(diào)元素間的關(guān)系。
在MainActivity中設(shè)置退出動(dòng)畫
//啟用轉(zhuǎn)場動(dòng)畫
window.requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)
window.exitTransition = MaterialSharedAxis(MaterialSharedAxis.X, true).apply {
//指定轉(zhuǎn)換視圖
addTarget(R.id.list)
//轉(zhuǎn)換不包含導(dǎo)航和狀態(tài)欄
excludeTarget(android.R.id.statusBarBackground, true)
excludeTarget(android.R.id.navigationBarBackground, true)
}
進(jìn)行跳轉(zhuǎn)
startActivity(
Intent(this, TestActivity::class.java),
ActivityOptions.makeSceneTransitionAnimation(this).toBundle()
)
在TestActivity中設(shè)置進(jìn)入動(dòng)畫
window.requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)
window.enterTransition = MaterialSharedAxis(MaterialSharedAxis.X, true).apply {
addTarget(R.id.display)
excludeTarget(android.R.id.statusBarBackground, true)
excludeTarget(android.R.id.navigationBarBackground, true)
}
然后,我們來看一下轉(zhuǎn)場效果

Fade Through
用于彼此之間沒有密切關(guān)系的界面元素之間的過渡,使用依序淡出和淡入的效果,并會(huì)對(duì)轉(zhuǎn)入的元素進(jìn)行縮放,用法跟MaterialSharedAxis差不多。
window.requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)
window.enterTransition = MaterialFadeThrough().apply {
addTarget(R.id.display)
excludeTarget(android.R.id.statusBarBackground, true)
excludeTarget(android.R.id.navigationBarBackground, true)
}

Fade
用于進(jìn)入或退出屏幕畫面范圍的界面元素。似乎效果上Fade 和上面的 Fade Through 差不多,其實(shí)確實(shí)都是透明度+縮放動(dòng)畫,但是官方建議,如果發(fā)生在同一個(gè)界面,例如在屏幕中心淡出的對(duì)話框。
這里為了更清楚的看清轉(zhuǎn)場過程,將動(dòng)畫的執(zhí)行時(shí)間duration設(shè)置為1000,實(shí)際開發(fā)中應(yīng)設(shè)置小點(diǎn),或者不用去設(shè)置
val materialFade = MaterialFade().apply {
duration = 1000L
}
TransitionManager.beginDelayedTransition(binding.list, materialFade)
binding.detail.visibility = View.VISIBLE

總結(jié)
在Android 轉(zhuǎn)場動(dòng)畫的發(fā)展中,早期的轉(zhuǎn)場支持平移、縮放、透明度、旋轉(zhuǎn)四種基礎(chǔ)動(dòng)畫效果,隨后,出現(xiàn)了Material Design 轉(zhuǎn)場動(dòng)畫,給我們帶來了共享元素動(dòng)畫效果,最后Material Motion 動(dòng)畫封裝了四種動(dòng)畫,使得轉(zhuǎn)場效果的實(shí)現(xiàn)更加容易。我覺得,頁面之間的轉(zhuǎn)場效果,可以賦予應(yīng)用活力,豐富用戶的使用體驗(yàn),升華應(yīng)用交互的靈魂,常言道,好看的皮囊千篇一律,有趣的靈魂萬里挑一。
到此這篇關(guān)于Android轉(zhuǎn)場動(dòng)畫深入分析探究的文章就介紹到這了,更多相關(guān)Android轉(zhuǎn)場動(dòng)畫內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Android?Flutter實(shí)現(xiàn)頁面切換轉(zhuǎn)場動(dòng)畫效果
- Android實(shí)現(xiàn)Reveal圓形Activity轉(zhuǎn)場動(dòng)畫的完整步驟
- Android工具欄頂出轉(zhuǎn)場動(dòng)畫的實(shí)現(xiàn)方法實(shí)例
- Android5.0之Activity的轉(zhuǎn)場動(dòng)畫的示例
- 詳解Android(共享元素)轉(zhuǎn)場動(dòng)畫開發(fā)實(shí)踐
- Android中轉(zhuǎn)場動(dòng)畫的實(shí)現(xiàn)與兼容性處理
- Android轉(zhuǎn)場效果實(shí)現(xiàn)示例淺析
相關(guān)文章
ffmpeg實(shí)現(xiàn)去水印以及切分視頻demo
這篇文章主要為大家介紹了ffmpeg實(shí)現(xiàn)去水印以及切分視頻demo,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11
Android開發(fā)應(yīng)用中Broadcast Receiver組件詳解
本篇文章主要介紹了Android開發(fā)應(yīng)用中Broadcast Receiver組件詳解,想要學(xué)習(xí)的同學(xué)可以了解一下。2016-11-11
Android入門之在Activity之間穿梭的Intent
Intent可以用來啟動(dòng)Activity(startActivity(Intent))、Serveice(startService(Intent))等組件,可以用來綁定Activity和Service以建立它們之間的通信(bindServiceConnaction(Intent,ServiceConnection,int)),可以作為Broadcast Intent發(fā)送給廣播接收器2021-10-10
Android自定義超級(jí)炫酷的ViewPage指示器
由于應(yīng)公司開發(fā)要求,有一個(gè)顏色漸變帶縮放的指示器,雖然網(wǎng)上很多大佬開源的指示器開源庫,但如果一直都是使用別人造的輪子,那么對(duì)于自身的能力是毫無提升作用的,即使是參考別人的,然后自己動(dòng)手寫一遍那對(duì)于自身來說也是一種升華2022-07-07
Android編程實(shí)現(xiàn)監(jiān)聽EditText變化的方法
這篇文章主要介紹了Android編程實(shí)現(xiàn)監(jiān)聽EditText變化的方法,涉及Android針對(duì)EditText的相關(guān)操作技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-11-11
android 中使用TableLayout實(shí)現(xiàn)表單布局效果示例
本篇文章主要介紹了android 中使用TableLayout實(shí)現(xiàn)表單布局效果示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-06-06
詳解 Kotlin Reference Basic Types, String, Array and Imports
這篇文章主要介紹了詳解 Kotlin Reference Basic Types, String, Array and Imports的相關(guān)資料,需要的朋友可以參考下2017-06-06
Android中使用TextView實(shí)現(xiàn)圖文混排的方法
向TextView或EditText中添加圖像比直接添加文本復(fù)雜一點(diǎn)點(diǎn),需要用到<img>標(biāo)簽。接下來通過本文給大家介紹Android中使用TextView實(shí)現(xiàn)圖文混排的方法,希望對(duì)大家有所幫助2016-02-02
Android基于API的Tabs3實(shí)現(xiàn)仿優(yōu)酷t(yī)abhost效果實(shí)例
這篇文章主要介紹了Android基于API的Tabs3實(shí)現(xiàn)仿優(yōu)酷t(yī)abhost效果,結(jié)合完整實(shí)例形式分析了Android實(shí)現(xiàn)優(yōu)酷界面效果的相關(guān)技巧,需要的朋友可以參考下2015-12-12

