activity+fragment的软件框架中,多级页面的fragment一般都有动画效果,现在将动画的实现方法总结如下。
方法一
- 重写fragment 的onCreateAnimation方法。
在fragment的基类中,重写onCreateAnimation方法,使得fragment有进入和退出的动画效果。
public abstract class ChildFragment extends Fragment {
public IContainerFragment getContainerFragment() {
Fragment parentFragment = getParentFragment();
if (parentFragment instanceof IContainerFragment) {
return (IContainerFragment) parentFragment;
}
return null;
}
protected boolean addFragmentToStack(ChildFragment fragment) {
IContainerFragment containerFragment = getContainerFragment();
if (containerFragment == null) {
return false;
}
containerFragment.addFragmentToStack(fragment);
return true;
}
@Override
public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
TranslateAnimation animation = null;
if (transit == FragmentTransaction.TRANSIT_FRAGMENT_OPEN) {
if (enter) {
animation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 1, Animation.RELATIVE_TO_SELF, 0,
Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0);
} else {
animation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, -1,
Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0);
}
} else if (FragmentTransaction.TRANSIT_FRAGMENT_CLOSE == transit) {
if (enter) {
animation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, -1, Animation.RELATIVE_TO_SELF, 0,
Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0);
} else {
animation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 1,
Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0);
}
}
if (animation == null) {
animation = new TranslateAnimation(0, 0, 0, 0);
}
animation.setDuration(300);
return animation;
}
}
注意,该方案,进入fragment用如下方法
@Override
public boolean addFragmentToStack(ChildFragment fragment) {
if (!isResumed() || !isAdded()) {
return false;
}
String simpleName = fragment.getClass().getSimpleName();
FragmentTransaction ft = getChildFragmentManager().beginTransaction();
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.replace(getContainerId(), fragment, simpleName);
ft.addToBackStack(null);
ft.commit();
getChildFragmentManager().executePendingTransactions();
return true;
}
退出fragment的方法为 getActivity().onBackPressed();
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.title_bar_left_btn:
getActivity().onBackPressed();
break;
}
}
方法二
使用Fragmentmanager 的add方法,commit之前设置动画
/**
* 弹出Fragment堆栈
*/
private static void onPopBackStack(FragmentActivity context) {
if(context == null) {
android.util.Log.e("", "Context is null.");
return;
}
FragmentManager manager = context.getSupportFragmentManager();
if(manager == null) {
android.util.Log.e("", "FragmentManager is null.");
return;
}
Fragment lastElement = getActiveFragment(context);
if(lastElement != null && lastElement.isAdded()) {
lastElement.onHiddenChanged(false);
}
manager.beginTransaction()
.setCustomAnimations(
R.anim.slide_left_out,R.anim.slide_right_out)
.remove(lastElement)
.commitAllowingStateLoss();
manager.popBackStack();
disableFragmentView(false,context);
}
/**
* 添加Fragment到堆栈
* @param fragmentTag Tag标记
* @param fragment Fragment实例
*/
public static void addToBackStack(FragmentActivity context, String fragmentTag, Fragment fragment) {
disableFragmentView(true,context);
FragmentManager manager = context.getSupportFragmentManager();
manager.beginTransaction()
.setCustomAnimations(
R.anim.slide_right_in,
R.anim.slide_left_out)
.add(R.id.content_fragment, fragment,fragmentTag)
.addToBackStack(fragmentTag).commitAllowingStateLoss();
disableContentFragment(context, true);
}
slide_left_in
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:duration="300"
android:toXDelta="0.0"
android:fromXDelta="-100.0%p" />
</set>
slide_left_out
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:duration="300"
android:fromXDelta="0.0"
android:toXDelta="-100.0%p" />
</set>
slide_right_in
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:duration="300"
android:fromXDelta="100.0%p"
android:toXDelta="0.0" />
</set>
slide_right_out
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:duration="300"
android:toXDelta="100.0%p"
android:fromXDelta="0.0" />
</set>