iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 14
2
Software Development

Android animation 30天上手系列 第 14

Day14 Activity transition

  • 分享至 

  • xImage
  •  

Activity transition 透過共同元素之間的動畫效果讓不同頁面間的轉換提供視覺連續效果。

在兩個Activity切換頁面時保持視覺連續性,透過共享元素(Share Element)讓畫面的切換更順暢。像這樣的轉場效果,在許多的app中都會看到

demo

可以看到第一頁的圖片、景點名稱,和第二頁是一樣的,設定一樣的Transition name,就可以達到上圖的效果。

[2頁的比較圖,圖片、景點 的對映]
two_activity

第一頁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 實踐


上一篇
Day13 LayoutTransition
下一篇
Day15 TransitionManager
系列文
Android animation 30天上手30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言