方法一:通過(guò)setCustomAnimations實(shí)現(xiàn)
在activity中開(kāi)啟fragment時(shí)诚啃,F(xiàn)ragmentTransaction在add()或replace()之前钮热,調(diào)用setCustomAnimations()來(lái)實(shí)現(xiàn)fragment轉(zhuǎn)場(chǎng)動(dòng)畫(huà);
getSupportFragmentManager()
.beginTransaction()
.setCustomAnimations(R.anim.slide_right_in,R.anim.slide_right_out,
R.anim.slide_right_in,R.anim.slide_right_out)
.add(R.id.framlayout,new AIFilePickerFragment())
.addToBackStack("")
.commit();
setCustomAnimations()方法還有一個(gè)兩個(gè)參數(shù)的重載方法可以使用;
該方法需要在資源文件res/anim下添加轉(zhuǎn)場(chǎng)動(dòng)畫(huà)红氯,如下:
- 進(jìn)場(chǎng)動(dòng)畫(huà)slide_right_in.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="@android:integer/config_mediumAnimTime">
<translate
android:toXDelta="0.0"
android:fromXDelta="100.0%p" />
</set>
- 出場(chǎng)動(dòng)畫(huà)slide_right_out.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="@android:integer/config_mediumAnimTime">
<translate
android:toXDelta="100.0%p"
android:fromXDelta="0.0" />
</set>
注意:1.該方法一定要在add或replace之前調(diào)用,否則無(wú)效;2.setCustomAnimations方法有一個(gè)很大的bug凭舶,就是在內(nèi)存重啟后所有設(shè)置的動(dòng)畫(huà)都將失效。
方法二: setTranseion和onCreateAnimation配合實(shí)現(xiàn)
setTranseion是FragmentTransaction的方法爱沟,而onCreateAnimation是Fragment的方法帅霜,一般兩個(gè)方法需要配合使用。而且它們不會(huì)像setCustomAnimations一樣钥顽,即使是內(nèi)存重啟也不會(huì)失效义屏,因?yàn)樗麄兪莿?dòng)態(tài)調(diào)用的。
先來(lái)看一下setTranseion方法:
/**
* Select a standard transition animation for this transaction. May be
* one of {@link #TRANSIT_NONE}, {@link #TRANSIT_FRAGMENT_OPEN},
* or {@link #TRANSIT_FRAGMENT_CLOSE}
*/
public abstract FragmentTransaction setTransition(@Transit int transit);
很明顯蜂大,要實(shí)現(xiàn)動(dòng)畫(huà)闽铐,我們只能傳TRANSIT_FRAGMENT_OPEN和TRANSIT_FRAGMENT_CLOSE,他們分別表示進(jìn)場(chǎng)和退場(chǎng)奶浦,首先使用FragmentTransaction設(shè)置Transeion:
getSupportFragmentManager()
.beginTransaction()
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
.add(R.id.framlayout,new AIFilePickerFragment())
.addToBackStack("")
.commit();
單獨(dú)使用setTranseion的話兄墅,F(xiàn)ragmentManager會(huì)生成默認(rèn)的動(dòng)畫(huà);源碼如下:
//根據(jù)transit或動(dòng)作拿animAttr
public static int transitToStyleIndex(int transit, boolean enter) {
int animAttr = -1;
switch (transit) {
case FragmentTransaction.TRANSIT_FRAGMENT_OPEN:
animAttr = enter ? ANIM_STYLE_OPEN_ENTER : ANIM_STYLE_OPEN_EXIT;
break;
case FragmentTransaction.TRANSIT_FRAGMENT_CLOSE:
animAttr = enter ? ANIM_STYLE_CLOSE_ENTER : ANIM_STYLE_CLOSE_EXIT;
break;
case FragmentTransaction.TRANSIT_FRAGMENT_FADE:
animAttr = enter ? ANIM_STYLE_FADE_ENTER : ANIM_STYLE_FADE_EXIT;
break;
}
return animAttr;
}
//根據(jù)animAttr生成動(dòng)畫(huà)
switch (styleIndex) {
case ANIM_STYLE_OPEN_ENTER:
return makeOpenCloseAnimation(mHost.getContext(), 1.125f, 1.0f, 0, 1);
case ANIM_STYLE_OPEN_EXIT:
return makeOpenCloseAnimation(mHost.getContext(), 1.0f, .975f, 1, 0);
case ANIM_STYLE_CLOSE_ENTER:
return makeOpenCloseAnimation(mHost.getContext(), .975f, 1.0f, 0, 1);
case ANIM_STYLE_CLOSE_EXIT:
return makeOpenCloseAnimation(mHost.getContext(), 1.0f, 1.075f, 1, 0);
case ANIM_STYLE_FADE_ENTER:
return makeFadeAnimation(mHost.getContext(), 0, 1);
case ANIM_STYLE_FADE_EXIT:
return makeFadeAnimation(mHost.getContext(), 1, 0);
}
setTranseion和和Fragment的onCreateAnimation配合使用:
public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
if (transit == FragmentTransaction.TRANSIT_FRAGMENT_OPEN) {//表示是一個(gè)進(jìn)入動(dòng)作澳叉,比如add.show等
if (enter) {//普通的進(jìn)入的動(dòng)作
return AnimationUtils.loadAnimation(getContext(), R.anim.anim_bottom_in);
} else {//比如一個(gè)已經(jīng)Fragmen被另一個(gè)replace隙咸,是一個(gè)進(jìn)入動(dòng)作,被replace的那個(gè)就是false
return AnimationUtils.loadAnimation(getContext(), R.anim.anim_out);
}
} else if (transit == FragmentTransaction.TRANSIT_FRAGMENT_CLOSE) {//表示一個(gè)退出動(dòng)作成洗,比如出棧五督,hide,detach等
if (enter) {//之前被replace的重新進(jìn)入到界面或者Fragment回到棧頂
return AnimationUtils.loadAnimation(getContext(), R.anim.anim_in);
} else {//Fragment退出瓶殃,出棧
return AnimationUtils.loadAnimation(getContext(), R.anim.anim_bottom_out);
}
}
return null;
}
transit對(duì)應(yīng)FragmentTransaction設(shè)置的動(dòng)作充包,onCreateAnimation在Fragment的每個(gè)操作動(dòng)作中都會(huì)被回調(diào),最好是配合FragmentTransaction的setTranseion方法使用,才能更加靈活的實(shí)現(xiàn)各種動(dòng)畫(huà)基矮,不然onCreateAnimation方法的transit參數(shù)永遠(yuǎn)是0淆储,而nextAnim與setCustomAnimations有關(guān),而一般不推薦使用setCustomAnimations家浇。