Activity transition 透過共同元素之間的動畫效果讓不同頁面間的轉換提供視覺連續效果。
在兩個Activity切換頁面時保持視覺連續性,透過共享元素(Share Element)讓畫面的切換更順暢。像這樣的轉場效果,在許多的app中都會看到
可以看到第一頁的圖片、景點名稱,和第二頁是一樣的,設定一樣的Transition name,就可以達到上圖的效果。
[2頁的比較圖,圖片、景點 的對映]
第一頁RecycleView 點下Item,開啟第二頁:
步驟1:取得imageView、title
步驟2:將imageView、title 設定Transition Name,這裡的Transition Name會與DetailActivity一樣
步驟3:startActivity,並將activityOptions傳入
override fun onItemClick(adapterView: AdapterView<*>?, view: View?, position: Int, id: Long) {
val item = adapterView!!.getItemAtPosition(position) as Scenery
val intent = Intent(this, DetailActivity::class.java)
intent.putExtra(DetailActivity.ARG_SCENERY_ID, item.sceneryId)
//步驟1:取得imageView、title
val imageView = view!!.findViewById<View>(R.id.sceneryImageView)
val title = view.findViewById<View>(R.id.sceneryTitle)
//步驟2:將imageView、title 設定Transition Name,這裡的Transition Name會與DetailActivity一樣
val activityOptions = ActivityOptionsCompat.makeSceneTransitionAnimation(
this,
Pair(imageView, DetailActivity.TRANSITION_SCENERY_IMAGE_NAME),
Pair(title, DetailActivity.TRANSITION_SCENERY_TITLE_NAME)
)
//步驟3:startActivity,並將activityOptions傳入
startActivity(intent, activityOptions.toBundle())
}
第二頁
將imageView與title與第一頁設定一樣的Transition name。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_detail)
scenery = Scenery.getItem(intent.getIntExtra(ARG_SCENERY_ID, 0))!!
//設定TransitionName
setTransitionName(sceneryImageView, TRANSITION_SCENERY_IMAGE_NAME)
setTransitionName(sceneryTitle, TRANSITION_SCENERY_TITLE_NAME)
loadData()
}
到目前為止已可以讓第一頁的imageView、title與第二頁的imageView、title在換頁時看起來有連續性。
為了讓載入更順暢,我們做了一張小圖及大圖。在頁面初始時先載入小圖,待動畫完成再載入大圖。
private fun loadData() {
sceneryTitle.text = scenery.name
sceneryDesc.text = scenery.desc
addTransitionListener()
//讀取小圖
loadThumbnail()
}
動畫完成時,載入大圖
private fun addTransitionListener(): Boolean {
val transition = window.sharedElementEnterTransition
if (transition != null) {
transition.addListener(object : Transition.TransitionListener {
override fun onTransitionResume(transition: Transition) {
}
override fun onTransitionPause(transition: Transition) {
}
override fun onTransitionStart(transition: Transition) {
}
override fun onTransitionEnd(transition: Transition) {
//動畫完成,載入大圖
loadFullSizeImage()
transition.removeListener(this)
}
override fun onTransitionCancel(transition: Transition) {
transition.removeListener(this)
}
})
return true
}
return false
}
完整程式:https://github.com/evanchen76/ActivityTransitionSample
參考:https://developer.android.com/training/transitions/start-activity
線上課程:
Android 動畫入門到進階
Android UI 進階實戰(Material Design Component)
出版書:
Android TDD 測試驅動開發:從 UnitTest、TDD 到 DevOps 實踐