改变片段过渡
Changing fragment transitions
我有几个片段,所有的片段都是从左到右进出的。我收到了一个新要求,即几个片段将有不同的退出过渡,而前一个片段将是静态的(不会有过渡)。如下图所示:
如果它有不同的转换,我首先在我的基本片段中添加抽象函数:
public abstract boolean hasDifferentTransitions();
之后我修改了要更改片段的函数:
public void replaceFragment(int container, Class<?> fragClass, Bundle b,boolean isSplash)
{
BaseFragment bf = null;
try
{
bf = (BaseFragment) fragClass.newInstance();
}
catch (Exception e)
{
e.printStackTrace();
}
String backStateName = bf.getClass().getSimpleName();
FragmentManager manager = getSupportFragmentManager();
//checking if I am on the same fragment
if(_currentFragment!=null)
{
String currentFragmentName = _currentFragment.getClass().getSimpleName();
if(currentFragmentName.equals(backStateName))//not allow same fragment to be twice in backstack one after the other
return;
}
//checking if the "new fragement" is in the backstack if so I will pop out all the fragments till the required one.
BaseFragment backStackFrag = (BaseFragment) manager.findFragmentByTag(backStateName);
if(backStackFrag!=null)
{
_currentFragment = backStackFrag;
for(int fIndex=manager.getBackStackEntryCount()-1;fIndex>=0;fIndex--) {
String currentFragName = manager.getBackStackEntryAt(fIndex).getName();
if (backStateName.equals(currentFragName)) {
break;
}
manager.popBackStack();
}
}
else {//new fragment - set the transitions by the hasDifferentTransitions returned value
_currentFragment = bf;
FragmentTransaction ft = manager.beginTransaction();
if (isSplash) {
ft.setTransition(FragmentTransaction.TRANSIT_NONE);
} else {
if(bf.hasDifferentTransitions())
{
ft.setCustomAnimations(R.anim.enter_from_left, R.anim.exit_to_right,R.anim.enter_from_right,R.anim.exit_to_left);
}
else
{
ft.setCustomAnimations(R.anim.enter_from_left, R.anim.exit_to_right);
}
}
ft.replace(container, bf, bf.getClass().getSimpleName());
ft.addToBackStack(bf.getClass().getSimpleName());
ft.commitAllowingStateLoss();
}
}
不幸的是,当我在 "special fragment" 然后打开 "regular fragment" 它们都从右向左移动时,它没有按需要工作,有时当我进入 "special fragment" 它打开时没有任何转换
经过多次尝试,我终于实现了这个需求。
在我的 baseActivity 中,我添加了一个变量来了解用户何时更改为 "special fragment"
private boolean _openedSingleFragment;
public boolean openedSingleFragment()
{
return _openedSingleFragment;
}
public void setOpenedSingleFragment(boolean state)
{
_openedSingleFragment = state;
}
然后在每个常规片段上我重写 onCreateAnimation 如下:
@Override
public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
Animation anim = super.onCreateAnimation(transit, enter, nextAnim);
if(enter && ((BaseActivity)getActivity()).openedSingleFragment())
{
anim = new Animation() {};
anim.setDuration(0);
}
return anim;
}
使用此代码,我只是在用户使用特殊片段并打开常规片段时删除输入 transition/animation。
我还在特殊片段中覆盖了onCreateAnimation
@Override
public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
Animation anim = super.onCreateAnimation(transit, enter, nextAnim);
if(enter)
{
((BaseActivity)getActivity()).setOpenedSingleFragment(false);
}
else
{
if (anim == null && nextAnim != 0) {
anim = AnimationUtils.loadAnimation(getActivity(), R.anim.exit_to_left);
}
}
return动画;
}
我只是在开始特殊片段的过渡时重置布尔值,当我打开其他片段时我正在加载指定的动画。
我有几个片段,所有的片段都是从左到右进出的。我收到了一个新要求,即几个片段将有不同的退出过渡,而前一个片段将是静态的(不会有过渡)。如下图所示:
如果它有不同的转换,我首先在我的基本片段中添加抽象函数:
public abstract boolean hasDifferentTransitions();
之后我修改了要更改片段的函数:
public void replaceFragment(int container, Class<?> fragClass, Bundle b,boolean isSplash)
{
BaseFragment bf = null;
try
{
bf = (BaseFragment) fragClass.newInstance();
}
catch (Exception e)
{
e.printStackTrace();
}
String backStateName = bf.getClass().getSimpleName();
FragmentManager manager = getSupportFragmentManager();
//checking if I am on the same fragment
if(_currentFragment!=null)
{
String currentFragmentName = _currentFragment.getClass().getSimpleName();
if(currentFragmentName.equals(backStateName))//not allow same fragment to be twice in backstack one after the other
return;
}
//checking if the "new fragement" is in the backstack if so I will pop out all the fragments till the required one.
BaseFragment backStackFrag = (BaseFragment) manager.findFragmentByTag(backStateName);
if(backStackFrag!=null)
{
_currentFragment = backStackFrag;
for(int fIndex=manager.getBackStackEntryCount()-1;fIndex>=0;fIndex--) {
String currentFragName = manager.getBackStackEntryAt(fIndex).getName();
if (backStateName.equals(currentFragName)) {
break;
}
manager.popBackStack();
}
}
else {//new fragment - set the transitions by the hasDifferentTransitions returned value
_currentFragment = bf;
FragmentTransaction ft = manager.beginTransaction();
if (isSplash) {
ft.setTransition(FragmentTransaction.TRANSIT_NONE);
} else {
if(bf.hasDifferentTransitions())
{
ft.setCustomAnimations(R.anim.enter_from_left, R.anim.exit_to_right,R.anim.enter_from_right,R.anim.exit_to_left);
}
else
{
ft.setCustomAnimations(R.anim.enter_from_left, R.anim.exit_to_right);
}
}
ft.replace(container, bf, bf.getClass().getSimpleName());
ft.addToBackStack(bf.getClass().getSimpleName());
ft.commitAllowingStateLoss();
}
}
不幸的是,当我在 "special fragment" 然后打开 "regular fragment" 它们都从右向左移动时,它没有按需要工作,有时当我进入 "special fragment" 它打开时没有任何转换
经过多次尝试,我终于实现了这个需求。 在我的 baseActivity 中,我添加了一个变量来了解用户何时更改为 "special fragment"
private boolean _openedSingleFragment;
public boolean openedSingleFragment()
{
return _openedSingleFragment;
}
public void setOpenedSingleFragment(boolean state)
{
_openedSingleFragment = state;
}
然后在每个常规片段上我重写 onCreateAnimation 如下:
@Override
public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
Animation anim = super.onCreateAnimation(transit, enter, nextAnim);
if(enter && ((BaseActivity)getActivity()).openedSingleFragment())
{
anim = new Animation() {};
anim.setDuration(0);
}
return anim;
}
使用此代码,我只是在用户使用特殊片段并打开常规片段时删除输入 transition/animation。
我还在特殊片段中覆盖了onCreateAnimation
@Override
public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
Animation anim = super.onCreateAnimation(transit, enter, nextAnim);
if(enter)
{
((BaseActivity)getActivity()).setOpenedSingleFragment(false);
}
else
{
if (anim == null && nextAnim != 0) {
anim = AnimationUtils.loadAnimation(getActivity(), R.anim.exit_to_left);
}
}
return动画; }
我只是在开始特殊片段的过渡时重置布尔值,当我打开其他片段时我正在加载指定的动画。