Android轉(zhuǎn)場(chǎng)動(dòng)畫(huà)一說(shuō)
所謂轉(zhuǎn)場(chǎng)動(dòng)畫(huà),通俗的講就是一個(gè)Activity跳轉(zhuǎn)到另一個(gè)Activity是的動(dòng)畫(huà)。
Activity的轉(zhuǎn)場(chǎng)動(dòng)畫(huà)很早就有了,5.0之前用的是overridePendingTransition()這個(gè)方法。在5.0之后,Google使用Material Design設(shè)計(jì)風(fēng)格,進(jìn)而有了的新的轉(zhuǎn)場(chǎng)轉(zhuǎn)場(chǎng)動(dòng)畫(huà)的誕生,效果還是挺炫酷的,下面我們先看下效果。
5.0之前的效果

使用方法:
在startActivity后加入以下代碼
startActivity(Intent(this@BeforeActivity,BeforeTwoActivity::class.java)
//Fade(淡入淡出)
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out)
//Slide(左右交錯(cuò))
//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(左右交錯(cuò))
//overridePendingTransition(android.R.anim.slide_in_left,android.R.anim.slide_out_right)
其實(shí)這里主要是靠overridePendingTransition(int enterAnim, int exitAnim)來(lái)加載動(dòng)畫(huà),顧名思義第一個(gè)參數(shù)是進(jìn)場(chǎng)動(dòng)畫(huà),第二個(gè)是出場(chǎng)動(dòng)畫(huà)。
這幾個(gè)效果是可以交互使用,比如進(jìn)場(chǎng)用Fade效果,出場(chǎng)用SLide效果。也可以使用自定義的效果,這里不細(xì)說(shuō)。當(dāng)然5.0后了類(lèi)似共享元素這類(lèi)的效果那就另當(dāng)別論了
5.0之后的效果(過(guò)度效果和共享元素)


說(shuō)到這里不得不說(shuō)Google在5.0MD設(shè)計(jì)中給我提供全新的過(guò)度動(dòng)畫(huà)ActivityOptions,以及兼容包ActivityOptionsCompat.下面來(lái)說(shuō)一說(shuō)它提供幾種過(guò)度效果的方法
第一種
ActivityOptionsCompat makeCustomAnimation(Context context,int enterResId, int exitResId)。
這個(gè)方法其實(shí)和上面的overridePendingTransition()方法使用其實(shí)差不多,第二個(gè)參數(shù)是進(jìn)場(chǎng)動(dòng)畫(huà),第三個(gè)是出場(chǎng)動(dòng)畫(huà)。(效果參考o(jì)verridePendingTransition()) 使用如下:
startActivity的時(shí)候:
ActivityCompat.startActivity(Intent(this@BeforeActivity,BeforeTwoActivity::class.java),
ActivityOptionsCompat.makeCustomAnimation(this@BeforeActivity,
android.R.anim.fade_in, android.R.anim.fade_out).toBundle())
finish的時(shí)候:
ActivityCompat.finishAfterTransition(this)
但是這個(gè)方法調(diào)用后,會(huì)發(fā)現(xiàn)并沒(méi)有什么軟用,沒(méi)有退出的動(dòng)畫(huà)。打斷點(diǎn)調(diào)試后發(fā)現(xiàn):
public boolean startExitBackTransition(final Activity activity) {
if (mEnteringNames == null || mCalledExitCoordinator != null) {
return false;
} else {
...
}
}
這個(gè)mEnteringNames一直是null,然后這個(gè)變量跟共享元素有關(guān):
/**
* The shared elements that the calling Activity has said that they transferred to this
* Activity.
* 調(diào)用Activity的共享元素表示已轉(zhuǎn)移到此Activity(請(qǐng)不要介意這個(gè)機(jī)翻,湊和看)
*/
private ArrayList<String> mEnteringNames;
因?yàn)檫@個(gè)兩個(gè)頁(yè)面之間涉及到共享元素,這里沒(méi)有使用到,所以要想這個(gè)有出場(chǎng)動(dòng)畫(huà),還是調(diào)用overridePendingTransition()來(lái)顯示(有更好的方法請(qǐng)告知,萬(wàn)分感謝)
第二種
ActivityOptionsCompat makeScaleUpAnimation(View source,int startX, int startY, int startWidth, int startHeight)
這個(gè)效果展示的某個(gè)小的區(qū)域放大至全屏顯示,效果如下:
這個(gè)方法第一個(gè)參數(shù)是目標(biāo)view(也就是想要放大的view),第二、三個(gè)參數(shù)是起始坐標(biāo),第四,五個(gè)參數(shù)是過(guò)度效果開(kāi)始的寬高度 使用如下:
startActivity的時(shí)候:
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的時(shí)候(這個(gè)沒(méi)什么回退效果,暫時(shí)沒(méi)找到解決方法,有更好的方法請(qǐng)告知,萬(wàn)分感謝):
ActivityCompat.finishAfterTransition(this)
第二種
ActivityOptionsCompat makeScaleUpAnimation(View source,int startX, int startY, int startWidth, int startHeight)
這個(gè)效果展示的某個(gè)小的區(qū)域放大至全屏顯示,效果如下:

這個(gè)方法第一個(gè)參數(shù)是目標(biāo)view(也就是想要放大的view),第二、三個(gè)參數(shù)是起始坐標(biāo),第四,五個(gè)參數(shù)是過(guò)度效果開(kāi)始的寬高度 使用如下:
startActivity的時(shí)候:
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的時(shí)候(這個(gè)沒(méi)什么回退效果,暫時(shí)沒(méi)找到解決方法,有更好的方法請(qǐng)告知,萬(wàn)分感謝):
ActivityCompat.finishAfterTransition(this)
第三種
ActivityOptionsCompat makeThumbnailScaleUpAnimation(View source,Bitmap thumbnail, int startX, int startY)
這個(gè)效果展示的一塊的Bitmpat進(jìn)行拉伸的動(dòng)畫(huà),效果如下:

這個(gè)方法第一個(gè)參數(shù)是目標(biāo)view(也就是想要放大的view),第二參數(shù)是需要放大的圖片,第四,五個(gè)參數(shù)是起始坐標(biāo) 使用如下:
startActivity的時(shí)候:
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的時(shí)候(這個(gè)沒(méi)什么回退效果,暫時(shí)沒(méi)找到解決方法,有更好的方法請(qǐng)告知,萬(wàn)分感謝):
ActivityCompat.finishAfterTransition(this)
第四種
ActivityOptionsCompat makeClipRevealAnimation(View source,int startX, int startY, int width, int height)
這個(gè)效果展示的從一個(gè)點(diǎn)以圓形漸變到滿屏,效果如下:

這個(gè)方法第一個(gè)參數(shù)是目標(biāo)view(也就是想要放大的view),第二、三個(gè)參數(shù)是起始坐標(biāo),第四,五個(gè)參數(shù)是過(guò)度效果開(kāi)始的寬高度 使用如下:
startActivity的時(shí)候:
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的時(shí)候(這個(gè)沒(méi)什么回退效果,暫時(shí)沒(méi)找到解決方法,有更好的方法請(qǐng)告知,萬(wàn)分感謝):
ActivityCompat.finishAfterTransition(this)
第五種
ActivityOptions CompatmakeSceneTransitionAnimation(Activity activity,Pair<View, String>... sharedElements)
這個(gè)展示的多種效果,效果如下:

這個(gè)方法第一個(gè)參數(shù)是目標(biāo)view(也就是想要放大的view),第二個(gè)參數(shù)是共享元素需要的(這里的效果不涉及) 使用如下:
startActivity的時(shí)候:
startActivity(Intent(this@AfterActivity, AfterTwoActivity::class.java),
ActivityOptionsCompat.makeSceneTransitionAnimation(this@AfterActivity).toBundle())
然后在跳轉(zhuǎn)后的頁(yè)面設(shè)置效果(這里是AfterTwoActivity):
//Explode
window.enterTransition = Explode()
window.exitTransition = Explode()
//Slide
window.enterTransition = Slide()
window.exitTransition = Slide()
//Fade
window.enterTransition = Fade()
window.exitTransition = Fade()
共享元素
所謂的共享元素指的是Activity A中一個(gè)View和Activity B中的一個(gè)View做一個(gè)平滑過(guò)渡的效果。
效果展示(類(lèi)似微信朋友圈的圖片放大效果) :

來(lái)看一下如何來(lái)讓兩個(gè)頁(yè)面之間的View做一個(gè)過(guò)渡:
1.在A和B的布局中為需要進(jìn)行過(guò)渡效果的View設(shè)置兩個(gè)相同的 android:transitionName = “標(biāo)識(shí)名稱”
-
2.1 在startActivity的時(shí)候(適用單個(gè)view過(guò)渡):
//第二參數(shù)傳入過(guò)渡的view,第三個(gè)參數(shù)傳入 android:transitionName 標(biāo)識(shí)名稱 startActivity(Intent(this@ShareElementActivity, ShareElementTwoActivity::class.java), ActivityOptions.makeSceneTransitionAnimation(this@ShareElementActivity,view,"shareImg").toBundle()) -
2.2 在startActivity的時(shí)候(適用多個(gè)個(gè)view過(guò)渡):
//其實(shí)就是把過(guò)個(gè)需要過(guò)渡的View集合起來(lái) 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())