Как отложить переход ввода фрагмента в Android Lollipop?

В Android Lollipop теги Activity#postponeEnterTransition() и Activity#startPostponedEnterTransition() дают Activity возможность откладывать запуск переходов между общими элементами до тех пор, пока не будут загружены все данные. Они отлично подходят для Activity переходов.

Есть ли способ добиться такого же эффекта при использовании переходов Fragment?




Ответы (2)


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

Чтобы получить эквивалент, вы можете добавить Фрагмент и скрыть его в транзакции, затем, когда Фрагмент будет готов, удалить старый Фрагмент и показать новый Фрагмент в транзакции.

getFragmentManager().beginTransaction()
    .add(R.id.container, fragment2)
    .hide(fragment2)
    .commit();

Позже, когда фрагмент2 будет готов:

getFragmentManager().beginTransaction()
    .addSharedElement(sharedElement, "name")
    .remove(fragment1)
    .show(fragment2)
    .commit();
person George Mount    schedule 18.11.2014
comment
Хорошо, но как нам отложить настройку фрагмента 1 после того, как мы закончим работу с фрагментом 2 и будет вызван FragmentManager.popBackStack()? - person mennovogel; 23.04.2015
comment
Если вы не удалите фрагмент1, а скроете его, это облегчит вам жизнь. В противном случае необходим дополнительный шаг, но он работает точно так же. a) добавить 2, скрыть 2 b) показать 2, скрыть, добавить в задний стек 1 c) показать 1, удалить1, добавить в задний стек. Затем вы обнаруживаете, что достигли (c) во второй раз, вы ждете, пока 1 будет готово, а затем программно извлекаете задний стек. - person George Mount; 23.04.2015
comment
@GeorgeMount У меня возникают проблемы с переходами фрагментов (согласно моему ТАК вопрос). Начинаю думать, что это из-за того, что мои фрагменты не готовы, когда начинается анимация. В вашем комментарии выше я понимаю шаги a) и b), но c) показать 1, удалить1, добавить в задний стек. Затем вы обнаруживаете, что достигли (c) во второй раз, вы ждете, пока 1 будет готово, а затем программно извлекаете задний стек. меня немного смущает. Можете ли вы немного расширить это? - person Sound Conception; 08.07.2015
comment
Надеюсь, это поможет: halfthought.wordpress.com/2015/06/ 04/ - person George Mount; 08.07.2015
comment
@ДжорджМаунт. Благодарю вас! Объяснение и образец проекта превосходны! - person Sound Conception; 09.07.2015
comment
Вы сказали позже, когда фрагмент будет готов, как вы узнаете, когда это произойдет? - person user3497504; 14.09.2015
comment
Это зависит от того, что вызывает задержку. В моем примере я жду, пока RecyclerView выполнит макет, добавив onPreDrawListener. В вашем приложении вам может потребоваться дождаться загрузки растрового изображения, активности базы данных или чего-то еще. - person George Mount; 15.09.2015
comment
Аллилуйя! Великолепно! - person Miloš Černilovský; 01.06.2016
comment
Но это изменилось с 2015 года, верно? Это возможно, но вы должны установить для Reordering значение true .. Или это другая история? - person Wecherowski; 12.08.2019
comment
Да. Это изменилось. Фрагментные переходы теперь существуют. - person George Mount; 13.08.2019

Вы можете отложить переход ввода фрагмента, выполнив следующие действия:

  • Разрешить FragmentTransaction повторно заказывать и оптимизировать транзакцию

    requireActivity().supportFragmentManager
      .beginTransaction()
      .replace(R.id.container, fragmentB)
      .addSharedElement(view, "transitionName")
      .setReorderingAllowed(true) // Set to true
      .commit()
    
  • Скажите фрагменту B отложить переход после создания представления

    class TransitionToFragment : Fragment(R.layout.fragment_b) {
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
      super.onViewCreated(view, savedInstanceState)
      postponeEnterTransition() // Don't start enter transitions yet!
    
      ... // Setup your views
    
      (view.parent as? View)?.doOnPreDraw { startPostponedEnterTransition() } // Ok, start transitions
    }
    }
    

    view.parent.doOnPreDraw { ... } используется для обеспечения того, чтобы виды фрагмента были измерены и размещены для перехода. Дополнительные сведения см. в блоге Криса Бейнса.

person Brown Smith    schedule 14.07.2020