Изменение переходов фрагментов

У меня есть несколько фрагментов, все фрагменты имеют вход и выход слева направо. Я получил новое требование, что несколько фрагментов будут иметь разные переходы выхода, в то время как предыдущий фрагмент будет статическим (не будет перехода). Как на изображении ниже:

введите здесь описание изображения

Я начал с добавления абстрактной функции в свой базовый фрагмент, если он имеет разные переходы:

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();
    }
}

К сожалению, это не работает должным образом, когда я нахожусь на «особом фрагменте», а затем открываю «обычный фрагмент», они оба перемещаются справа налево, также иногда, когда я захожу на «особый фрагмент», он открывается без каких-либо переходов


person Anton Makov    schedule 27.11.2015    source источник


Ответы (1)


После многих попыток мне удалось реализовать это требование. В моей baseActivity я добавил эту переменную, чтобы знать, когда пользователь переходит на «специальный фрагмент».

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;
}

с помощью этого кода я просто удаляю входящий переход/анимацию, когда пользователь находится на специальном фрагменте, и открываю обычный.

Я также переопределяю 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);
        }
    }

вернуть анимацию; }

Я сбрасываю логическое значение только при запуске перехода специального фрагмента, а при открытии других фрагментов загружаю указанную анимацию.

person Anton Makov    schedule 27.11.2015