MTransition
最近寫了一個動畫庫,叫MTransition,顧名思義,就是過場動畫、頁面切換動畫用的。它可以提高你開發(fā)頁面切換動畫的效率,用一些簡單的代碼實現(xiàn)非常復(fù)雜的動畫??鏏ctivity的動畫也適用。
現(xiàn)在代碼已經(jīng)開源,歡迎大家Star:https://github.com/HJ-Money/MTransition
Demo Apk
下載鏈接:https://github.com/HJ-Money/MTransition/raw/master/Introduction/mtransition_demo.apk

先看效果

在上面的動圖示例中,動畫執(zhí)行前后分別是兩個不同的Activity。如下圖:


像這種跨Activity的切換動畫是現(xiàn)有技術(shù)比較難實現(xiàn)的,并且還需要響應(yīng)用戶的跟手操作。MTransition非常適合這種情況。
作為開發(fā)者的你,只需要完成兩個Activity的UI開發(fā)即可,中間的過渡動畫交給MTransiton處理,MTransiton可以完美實現(xiàn)你需要的各種頁面切換\過渡動畫,節(jié)省你的開發(fā)時間。
更多示例請看倉庫代碼或者SlidingActivity
需求背景
之前在各種項目中寫過很多頁面切換的動畫,從我自身的經(jīng)驗來說,寫這些過場動畫存在以下痛點:
1、由于這些動畫往往涉及兩個不同模塊的頁面,所以代碼很容易將兩個模塊耦合在一起;
2、大部分過場動畫的動畫驅(qū)動層代碼是非常類似的,僅僅是動畫的元素和動畫路徑不一樣。這樣每次寫一個新的動畫,都有一部分代碼以前寫過,現(xiàn)在不得不又寫一遍。重復(fù)代碼多,重復(fù)造輪子;
3、有很多動畫其實效果很簡單,但是由于需要計算位置,計算動畫屬性值,各種繁瑣的計算,然后又需要控制View的顯示和消失等,有時候View的寬高還不確定,要等第一幀繪制完之后才能做動畫,結(jié)果代碼就分開好幾塊地方。這些都繁瑣的小問題堆在一起,導(dǎo)致代碼看起來相當(dāng)復(fù)雜,可讀性也不強(qiáng);
所以我就想做一個過場動畫的庫MTransition,解決這些問題,節(jié)省開發(fā)成本。
使用MTransition
MTransition適用于所有頁面的切換動畫,這里的頁面不一定是Activity,也可以是Fragment、Window或者是同一個Activity的兩個View,但是頁面必須是占滿整個屏幕的,否則可能會出現(xiàn)效果不符合預(yù)期。
你可以通過Gradle引用它:
compile 'com.mjun:mtransition:0.1.3'
現(xiàn)假設(shè)我們需要實現(xiàn)一個從頁面A(FromPage)到頁面B(ToPage)的過渡動畫,首先我們先完成頁面A和頁面B本身的UI開發(fā),然后可以用MTransition完成過渡動畫。
基礎(chǔ)用法
step1、在頁面A打開頁面B之前創(chuàng)建MTransition,并設(shè)置頁面A最外層的View給MTransition:
final MTransition transition = MTransitionManager.getInstance().createTransition("example");
transition.fromPage().setContainer(mContainerView, new ITransitPrepareListener() {
@Override
public void onPrepare(MTransitionView container) {
// 傳遞需要做動畫的View
transition.fromPage().addTransitionView("icon", mIconView);
...
}
});
step2、在頁面B創(chuàng)建之后,且在頁面顯示之前,設(shè)置頁面B最外層的View給MTransition,同時告訴MTransition頁面的View要做哪些動畫,調(diào)整View順序等:
final MTransition transition = MTransitionManager.getInstance().getTransition("example");
transition.toPage().setContainer(mContainerView, new ITransitPrepareListener() {
@Override
public void onPrepare(MTransitionView container) {
// 設(shè)置動畫屬性
container.alpha(0f, 1f);
MTransitionView icon = transition.toPage().addTransitionView("icon", mImageView);
transition.fromPage().getTransitionView("icon").above(icon).transitTo(icon, true);
}
});
step3、設(shè)置動畫時長,然后start MTransition,一個過渡動畫即完成
transition.setDuration(500);
transition.start();
NOTE:
1、如果頁面A和B是Activity的話,因為Activity默認(rèn)是有Activity的進(jìn)場退場動畫,所以需要在startActivity()和finish()之后調(diào)用以下代碼:
startActivity(intent);
MTranstionUtil.removeActivityAnimation(this);
finish();
MTranstionUtil.removeActivityAnimation(this);
2、在確定不再需要當(dāng)前頁面的MTransition時,請務(wù)必調(diào)用destoryTransition()來銷毀MTransition,不然會內(nèi)存泄漏:
MTransitionManager.getInstance().destoryTransition("example");
進(jìn)階用法
反向動畫
在頁面B返回頁面A時,你很有可能需要剛才的過渡動畫反向執(zhí)行一次,這時候可以調(diào)用reverse(),執(zhí)行一遍反向動畫,當(dāng)然你可以隨時改變動畫路徑,
例如你可以改變動畫時長、甚至完全換一個過渡動畫;
final MTransition transition = MTransitionManager.getInstance().getTransition("example");
transition.reverse();
定格動畫
你可以調(diào)用setProgress()讓動畫停留在你想要的地方,因此你可以利用這點實現(xiàn)跟手動畫,具體請參考本倉庫代碼;
自定義動畫
MTransition已經(jīng)提供了一堆基礎(chǔ)的動畫api,例如平移、旋轉(zhuǎn)、縮放、透明度等。這些api已經(jīng)可以滿足大部分需求,但是如果你需要一些形變或者更加復(fù)雜的動畫,
你就需要自定義動畫。
step1、將你的自定義動畫View實現(xiàn)ITransitional接口
step2、調(diào)用replaceBy()接口,將你的自定義動畫View替換原本的View,讓它在過渡動畫過程中做動畫
該方案可以結(jié)合Lottie或者其他動畫庫,實現(xiàn)一些非常酷炫的效果,如下圖,具體請參考本倉庫代碼中的Demo5、6、7;


其他
各種用法請詳細(xì)參考MTransition的Demo代碼。
SlidingActivity
SlidingActivity是一個基于MTransition做的UI框架,你不需要改動任何代碼,只需讓你的Activity繼承倉庫中的BaseTransitionActivity,就可以自動實現(xiàn)邊緣滑動過場動畫。更多效果可以自己改造自定義。
具體請參考:https://github.com/HJ-Money/SlidingActivity
MTransition的優(yōu)點
1、提升效率,實現(xiàn)簡單,實現(xiàn)上面的效果只需極少的核心代碼;
2、解耦,頁面模塊不再有交集,非常獨立,并且所有動畫相關(guān)的代碼都交給MTransition處理,頁面只寫布局即可,頁面內(nèi)不需要再處理動畫,只需向MTransition配置你的動畫路徑;
3、將底層的動畫框架封裝起來,減少重復(fù)代碼,同時把計算的代碼都處理好;
4、可以實現(xiàn)跨Activity的過渡,也可實現(xiàn)同一個Activity不同View切換的動畫;
5、幾乎可以在不修改原有代碼的基礎(chǔ)上,為頁面切換增加過渡動畫;
6、支持自定義(可以結(jié)合Lottie),可以實現(xiàn)的效果十分豐富,沒有上限;
7、天生支持跟手動畫,原路徑回退動畫(其實就是可以控制動畫的進(jìn)度);
更詳細(xì)的使用說明
更詳細(xì)的使用說明,請看下一篇文章:MTransition使用示例、Q&A