Android轉場動畫一說

MagicFrost發表於2019-03-04

Android轉場動畫一說

所謂轉場動畫,通俗的講就是一個Activity跳轉到另一個Activity是的動畫。

Activity的轉場動畫很早就有了,5.0之前用的是overridePendingTransition()這個方法。在5.0之後,Google使用Material Design設計風格,進而有了的新的轉場轉場動畫的誕生,效果還是挺炫酷的,下面我們先看下效果。

5.0之前的效果


Android轉場動畫一說

使用方法:

在startActivity後加入以下程式碼

startActivity(Intent(this@BeforeActivity,BeforeTwoActivity::class.java)
//Fade(淡入淡出)
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out)
//Slide(左右交錯)
//overridePendingTransition(android.R.anim.slide_in_left, android.R.anim.slide_out_right)
複製程式碼

然後在finish後加入以下程式碼

finish()
//Fade(淡入淡出)
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out)
//Slide(左右交錯)
//overridePendingTransition(android.R.anim.slide_in_left,android.R.anim.slide_out_right)
複製程式碼

其實這裡主要是靠overridePendingTransition(int enterAnim, int exitAnim)來載入動畫,顧名思義第一個引數是進場動畫,第二個是出場動畫。 這幾個效果是可以互動使用,比如進場用Fade效果,出場用SLide效果。也可以使用自定義的效果,這裡不細說。當然5.0後了類似共享元素這類的效果那就另當別論了

5.0之後的效果(過度效果和共享元素)


Android轉場動畫一說 Android轉場動畫一說

說到這裡不得不說Google在5.0MD設計中給我提供全新的過度動畫ActivityOptions,以及相容包ActivityOptionsCompat.下面來說一說它提供幾種過度效果的方法

第一種

ActivityOptionsCompat makeCustomAnimation(Context context,int enterResId, int exitResId)。

這個方法其實和上面的overridePendingTransition()方法使用其實差不多,第二個引數是進場動畫,第三個是出場動畫。(效果參考overridePendingTransition()) 使用如下:

startActivity的時候:

ActivityCompat.startActivity(Intent(this@BeforeActivity,BeforeTwoActivity::class.java),
                ActivityOptionsCompat.makeCustomAnimation(this@BeforeActivity,
                android.R.anim.fade_in, android.R.anim.fade_out).toBundle())
複製程式碼

####finish的時候:

ActivityCompat.finishAfterTransition(this)
複製程式碼

但是這個方法呼叫後,會發現並沒有什麼軟用,沒有退出的動畫。打斷點除錯後發現:

public boolean startExitBackTransition(final Activity activity) {
    if (mEnteringNames == null || mCalledExitCoordinator != null) {
        return false;
    } else {
        ...
    }
}
複製程式碼

這個mEnteringNames一直是null,然後這個變數跟共享元素有關:

/**
 * The shared elements that the calling Activity has said that they transferred to this
 * Activity.
 * 呼叫Activity的共享元素表示已轉移到此Activity(請不要介意這個機翻,湊和看)
 */
private ArrayList<String> mEnteringNames;
複製程式碼

因為這個兩個頁面之間涉及到共享元素,這裡沒有使用到,所以要想這個有出場動畫,還是呼叫overridePendingTransition()來顯示(有更好的方法請告知,萬分感謝)

第二種

ActivityOptionsCompat makeScaleUpAnimation(View source,int startX, int startY, int startWidth, int startHeight)

這個效果展示的某個小的區域放大至全屏顯示,效果如下:

這個方法第一個引數是目標view(也就是想要放大的view),第二、三個引數是起始座標,第四,五個引數是過度效果開始的寬高度 使用如下:

startActivity的時候:

val options = ActivityOptionsCompat.makeScaleUpAnimation(view,view.width/2,view.height/2,
0, 0)
ActivityCompat.startActivity(this@AfterActivity,Intent(this@AfterActivity,AfterTwoActivity::class.java),options.toBundle())
複製程式碼

finish的時候(這個沒什麼回退效果,暫時沒找到解決方法,有更好的方法請告知,萬分感謝):

ActivityCompat.finishAfterTransition(this)
複製程式碼

第二種

ActivityOptionsCompat makeScaleUpAnimation(View source,int startX, int startY, int startWidth, int startHeight)

這個效果展示的某個小的區域放大至全屏顯示,效果如下:


Android轉場動畫一說

這個方法第一個引數是目標view(也就是想要放大的view),第二、三個引數是起始座標,第四,五個引數是過度效果開始的寬高度 使用如下:

startActivity的時候:

val options = ActivityOptionsCompat.makeScaleUpAnimation(view,view.width/2,view.height/2,
0, 0)
ActivityCompat.startActivity(this@AfterActivity,Intent(this@AfterActivity,AfterTwoActivity::class.java),options.toBundle())
複製程式碼

finish的時候(這個沒什麼回退效果,暫時沒找到解決方法,有更好的方法請告知,萬分感謝):

ActivityCompat.finishAfterTransition(this)
複製程式碼

第三種

ActivityOptionsCompat makeThumbnailScaleUpAnimation(View source,Bitmap thumbnail, int startX, int startY)

這個效果展示的一塊的Bitmpat進行拉伸的動畫,效果如下:


Android轉場動畫一說

這個方法第一個引數是目標view(也就是想要放大的view),第二引數是需要放大的圖片,第四,五個引數是起始座標 使用如下:

startActivity的時候:

var bitmap = BitmapFactory.decodeResource(resources,effect.uri)
val options = ActivityOptionsCompat.makeThumbnailScaleUpAnimation(view, bitmap,
                            view.width/2, view.height/2)
ActivityCompat.startActivity(this@AfterActivity,Intent(this@AfterActivity,AfterTwoActivity::class.java),options.toBundle())
複製程式碼

finish的時候(這個沒什麼回退效果,暫時沒找到解決方法,有更好的方法請告知,萬分感謝):

ActivityCompat.finishAfterTransition(this)
複製程式碼

第四種

ActivityOptionsCompat makeClipRevealAnimation(View source,int startX, int startY, int width, int height)

這個效果展示的從一個點以圓形漸變到滿屏,效果如下:


Android轉場動畫一說

這個方法第一個引數是目標view(也就是想要放大的view),第二、三個引數是起始座標,第四,五個引數是過度效果開始的寬高度 使用如下:

startActivity的時候:

val options = ActivityOptionsCompat.makeClipRevealAnimation(view,view.width/2,
                            view.height/2,0, 0)
ActivityCompat.startActivity(this@AfterActivity,Intent(this@AfterActivity,AfterTwoActivity::class.java),options.toBundle())
複製程式碼

finish的時候(這個沒什麼回退效果,暫時沒找到解決方法,有更好的方法請告知,萬分感謝):

ActivityCompat.finishAfterTransition(this)
複製程式碼

第五種

####ActivityOptions CompatmakeSceneTransitionAnimation(Activity activity,Pair<View, String>... sharedElements)

這個展示的多種效果,效果如下:


Android轉場動畫一說

這個方法第一個引數是目標view(也就是想要放大的view),第二個引數是共享元素需要的(這裡的效果不涉及) 使用如下:

startActivity的時候:

startActivity(Intent(this@AfterActivity, AfterTwoActivity::class.java),
	ActivityOptionsCompat.makeSceneTransitionAnimation(this@AfterActivity).toBundle())
複製程式碼

然後在跳轉後的頁面設定效果(這裡是AfterTwoActivity):

//Explode
window.enterTransition = Explode()
window.exitTransition = Explode()
//Slide
window.enterTransition = Slide()
window.exitTransition = Slide()
//Fade
window.enterTransition = Fade()
window.exitTransition = Fade()
複製程式碼

共享元素

所謂的共享元素指的是Activity A中一個View和Activity B中的一個View做一個平滑過渡的效果。

效果展示(類似微信朋友圈的圖片放大效果) :


Android轉場動畫一說

來看一下如何來讓兩個頁面之間的View做一個過渡:

  • 1.在A和B的佈局中為需要進行過渡效果的View設定兩個相同的 android:transitionName = “標識名稱”

  • 2.1 在startActivity的時候(適用單個view過渡):

      //第二引數傳入過渡的view,第三個引數傳入 android:transitionName 標識名稱
      startActivity(Intent(this@ShareElementActivity, ShareElementTwoActivity::class.java),
      ActivityOptions.makeSceneTransitionAnimation(this@ShareElementActivity,view,"shareImg").toBundle())
    複製程式碼
  • 2.2 在startActivity的時候(適用多個個view過渡):

      //其實就是把過個需要過渡的View集合起來
      var one = android.support.v4.util.Pair<View, String>(img5, "shareImg5")
    
      var two = android.support.v4.util.Pair<View, String>(img6, "shareImg6")
    
      var pairs = arrayOf(one,two)
    
      val transitionActivityOptions = ActivityOptionsCompat.makeSceneTransitionAnimation(this, *pairs)
          startActivity(Intent(this@ShareElementActivity, ShareElementThreeActivity::class.java),
                  transitionActivityOptions.toBundle())
    複製程式碼

以上就是要說的轉場動畫,如若有不恰當的地方,歡迎指正

這是文中涉及的程式碼Demo地址

相關文章