Android轉(zhuǎn)場動畫深入分析探究
早期的轉(zhuǎn)場
最初,兩個Activity之間的切換的過度動畫,都是用overridePendingTransition。它只支持平移、縮放、透明度、旋轉(zhuǎn)四種動畫效果。
比如我們寫個平移跳轉(zhuǎn)動畫,實現(xiàn)是這樣的。首先,我們在資源文件anim下新建兩個動畫資源文件 enter_anim.xml 和 quit_anim.xml,分別表示進入和退出的動畫。
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)的時候,調(diào)用overridePendingTransition就行啦
startActivity(Intent(this, TestActivity::class.java)) overridePendingTransition(R.anim.enter_anim, R.anim.quit_anim)
Material Design 轉(zhuǎn)場動畫
Android 5.0之后使用,具有三種轉(zhuǎn)場動畫效果:
- Explode:爆炸式,將視圖移入場景中心或從中移出
- Fade:淡入淡出式,通過更改透明度來添加和移出視圖
- Slide:滑動式,從場景的一個邊緣移入或移出視圖
Materia轉(zhuǎn)場有兩種啟用方式,一種是在theme中設置 windowActivityTransitions
<style name="Theme.AndroidApp" parent="Theme.MaterialComponents.DayNight.DarkActionBar"> <item name="android:windowActivityTransitions">true</item> </style>
一種是通過代碼開啟
window.requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)
下面,通過一個簡單的示例,來瞧瞧具體是怎么去使用的
在MainActivity中設置退出動畫,然后通過點擊事件去進行跳轉(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() //退出動畫 } 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中設置進入動畫,這樣淡入淡出式就完成了
class TestActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { window.run { requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS) enterTransition = Fade() //進入動畫 } super.onCreate(savedInstanceState) val binding = ActivityTestBinding.inflate(layoutInflater) setContentView(binding.root) } }
共享元素
如下所示,共享元素的效果很有趣,看著就像是圖片從一個頁面放大到另一個頁面
共享元素過渡方式有四種
- changeBounds:為目標視圖布局邊界的變化添加動畫效果
- changeClipBounds:為目標視圖裁剪邊界的變化添加動畫效果
- changeTransform:為目標視圖縮放和旋轉(zhuǎn)方面的變化添加動畫效果
- changeImageTransform:為目標圖片尺寸和縮放方面的變化添加動畫效果
首先需要設置transitionName,告訴系統(tǒng),哪個View需要做動畫,然后進行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()) }
在目標Activity中給View設置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" } }
如果要使用多個共享元素,可使用Pair,例如
val options = ActivityOptionsCompat.makeSceneTransitionAnimation( this, Pair(binding.imageView, "imageView"), Pair(binding.signature, "signature") )
Material Motion 動畫
它提供了四種模式,可以根據(jù)需求靈活選用,分別是:
MaterialContainerTransform
用于包含容器的界面元素之間的過渡,通過將一個UI元素無縫轉(zhuǎn)換為另一個UI元素,在兩個不同的界面元素之間創(chuàng)造可視化的連接,跟之前共享元素動畫最大的不同點在于它可以是一個 ViewGroup,也可以是一個 View。
下面,我們通過一個簡單的例子來感受一下效果,item是個LinearLayout,用于點擊跳轉(zhuǎn)。
class MainActivity : AppCompatActivity() { private lateinit var binding: ActivityMainBinding override fun onCreate(savedInstanceState: Bundle?) { //1.啟用轉(zhuǎn)場動畫 window.requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS) setExitSharedElementCallback(MaterialContainerTransformSharedElementCallback()) super.onCreate(savedInstanceState) binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) initView() } private fun initView() { //2.設置transitionName binding.item.transitionName = "share" binding.item.setOnClickListener { //3.進行頁面跳轉(zhuǎn) startActivity( Intent(this, TestActivity::class.java), ActivityOptions.makeSceneTransitionAnimation(this, it, "share").toBundle() ) } } }
在目標Activity中,只顯示了幾行文本,整體用LinearLayout做容器,id為display。
這里為了更加清楚的看到動畫的轉(zhuǎn)換過程,我將動畫的執(zhí)行時間duration設置為2秒,實際開發(fā)中,不能搞這么久哦。
class TestActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { //1.啟用轉(zhuǎn)場動畫 window.requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS) setEnterSharedElementCallback(MaterialContainerTransformSharedElementCallback()) super.onCreate(savedInstanceState) val binding = ActivityTestBinding.inflate(layoutInflater) setContentView(binding.root) //2.設置transitionName binding.display.transitionName = "share" //3.設置具體的動畫 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有兩個屬性需要注意下:
- scrimColor:用于控制在動畫容器后面繪制的半透明陰影的顏色。默認情況下,該元素會設為 32% 黑色。這里將其設為透明,這意味著不會繪制任何紗罩。
- setAllContainerColors:在兩個視圖之間添加動畫時,它會在畫布上繪制 3 個容器: 后臺容器 ,起始視圖的容器和結束視圖的容器。對于這 3 個容器,我們都可以為其填充顏色,并將其默認設為透明。如果您的起始視圖或結束視圖本身沒有繪制背景,導致在動畫播放期間其他元素顯示在其下層,那么設置這些背景填充顏色可能會很有用。我們可以使用 setAllContainerColors 來統(tǒng)一顏色,確保我們不會遇到任何視覺問題。
Shared axis
用于具有空間或?qū)Ш疥P系的界面元素之間的過渡,讓元素在轉(zhuǎn)換時共用 x 軸、y 軸或 z 軸,用以強調(diào)元素間的關系。
在MainActivity中設置退出動畫
//啟用轉(zhuǎn)場動畫 window.requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS) window.exitTransition = MaterialSharedAxis(MaterialSharedAxis.X, true).apply { //指定轉(zhuǎn)換視圖 addTarget(R.id.list) //轉(zhuǎn)換不包含導航和狀態(tài)欄 excludeTarget(android.R.id.statusBarBackground, true) excludeTarget(android.R.id.navigationBarBackground, true) }
進行跳轉(zhuǎn)
startActivity( Intent(this, TestActivity::class.java), ActivityOptions.makeSceneTransitionAnimation(this).toBundle() )
在TestActivity中設置進入動畫
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
用于彼此之間沒有密切關系的界面元素之間的過渡,使用依序淡出和淡入的效果,并會對轉(zhuǎ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
用于進入或退出屏幕畫面范圍的界面元素。似乎效果上Fade 和上面的 Fade Through 差不多,其實確實都是透明度+縮放動畫,但是官方建議,如果發(fā)生在同一個界面,例如在屏幕中心淡出的對話框。
這里為了更清楚的看清轉(zhuǎn)場過程,將動畫的執(zhí)行時間duration設置為1000,實際開發(fā)中應設置小點,或者不用去設置
val materialFade = MaterialFade().apply { duration = 1000L } TransitionManager.beginDelayedTransition(binding.list, materialFade) binding.detail.visibility = View.VISIBLE
總結
在Android 轉(zhuǎn)場動畫的發(fā)展中,早期的轉(zhuǎn)場支持平移、縮放、透明度、旋轉(zhuǎn)四種基礎動畫效果,隨后,出現(xiàn)了Material Design 轉(zhuǎn)場動畫,給我們帶來了共享元素動畫效果,最后Material Motion 動畫封裝了四種動畫,使得轉(zhuǎn)場效果的實現(xiàn)更加容易。我覺得,頁面之間的轉(zhuǎn)場效果,可以賦予應用活力,豐富用戶的使用體驗,升華應用交互的靈魂,常言道,好看的皮囊千篇一律,有趣的靈魂萬里挑一。
到此這篇關于Android轉(zhuǎn)場動畫深入分析探究的文章就介紹到這了,更多相關Android轉(zhuǎn)場動畫內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Android屏幕適配工具類 Android自動生成不同分辨率的值
這篇文章主要為大家詳細介紹了Android屏幕適配工具類,Android自動生成不同分辨率的值,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-03-03Android 讀取文件內(nèi)容實現(xiàn)方法總結
這篇文章主要介紹了Android 讀取文件內(nèi)容實現(xiàn)方法的相關資料,這里提供了幾種方法,大家可以選擇使用,需要的朋友可以參考下2016-10-10Android 開發(fā) 使用WebUploader解決安卓微信瀏覽器上傳圖片中遇到的bug
這篇文章主要介紹了Android 開發(fā) 使用WebUploader解決安卓微信瀏覽器上傳圖片中遇到的bug問題,本文給介紹的非常詳細,需要的朋友可以參考下2016-11-11