У меня проблема с переходом между фрагментами. Переход между фрагментами A и B очень прерывистый, как видно из этого GIF: https://imgur.com/a/PDogrxV. Если вы заметите, когда я нажимаю потрясающую кнопку, переход останавливается в середине экрана. Я попытался отладить его, замедляя анимацию, и вот результат (с боковым переходом): https://imgur.com/a/1ipQvfW
У меня есть фрагмент NavigationBar, в котором есть FrameLayout, в который я добавляю свой recyclerViewFragment (который наследуется от BaseFragment). Моя цель на самом деле - сгладить переход, чтобы не было «прерывистости» между фрагментом A (без сопряженного устройства) и B, который содержит представление рециркулятора, как показано в первой ссылке GIF,
Для справки:
Пример NavigationController (который наследует от моего фрагмента NavBar):
public class ExampleController extends NavBarFragment {
public static ExampleController newInstance() {
ExampleController fragment = new ExampleController();
fragment.setArguments(fragment.createInitBundle());
return fragment;
}
@Override
protected BaseFragment rootFragment() {
return RecyclerViewFragment.newInstance();
}
@Override
public Bundle createInitBundle() {
return new Bundle();
}
}
Метод rootFrament () вызывается в методе initializeLayout, найденном в NavBarFragment (который вызывается в OnCreateView ()) - это просто для придания некоторого контекста:
@Override
protected void initializeLayout(View view) {
super.initializeLayout(view);
this.toolbar.setNavigationOnClickListener(this::navigationButtonClick);
this.toolbar.setOnMenuItemClickListener(this::navigationMenuClick);
progressBar.getLayoutParams().height = 0;
progressBar.requestLayout();
this.setContentFragment(view, this.rootFragment());
}
и setContentFragment вызывает диспетчер транзакций:
private void setContentFragment(View view, BaseFragment frag) {
Context context = getActivity() != null ? getActivity().getApplicationContext() : null;
if (frag == null || view == null || context == null) {
return;
}
this.currentFragment = frag;
configureUIComponents(context, frag, 0);
getChildFragmentManager().beginTransaction()
.replace(view.findViewById(R.id.main_container).getId(), frag, createFragmentTag(0))
.commit();
}
Пример RecyclerViewFragment:
public class RecyclerViewFragment extends BaseRecyclerViewFragment {
public static RecyclerViewFragment newInstance(){
//navbar implement
Bundle args = new Bundle();
args.putString(NavigationBarConfig.KEY_NAV_BAR_TITLE, "Paired Devices");
args.putBoolean(NavigationBarConfig.KEY_SHOW_NAV_BAR, true);
args.putBoolean(FloatingActionButtonConfig.KEY_SHOW_FAB_BUTTON, true);
RecyclerViewFragment fragment = new RecyclerViewFragment();
fragment.setArguments(args);
return fragment;
}.
Я пробовал несколько вещей: 1) Я пытался использовать слушатели для «конца» перехода, чтобы дождаться загрузки данных. Это было основано на вопросе переполнения стека: Неправильный переход вложенных фрагментов . Я реализовал это следующим образом (я не буду делиться всем кодом по причинам). Метод didDisappear / didAppear () затем используется при загрузке моей модели:
@Override
public Animator onCreateAnimator(int transit, boolean enter, int nextAnim) {
Animator animator = null;
// Check for "Show" Transition ids
if (showTransitionAnimationIds.contains(nextAnim)) {
animator = AnimatorInflater.loadAnimator(getActivity(), nextAnim);
if (animator != null && enter) {
animator.addListener(new TransitionAnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
if (previousFragment != null) {
previousFragment.willDisappear();
}
willAppear();
}
@Override
public void onAnimationEnd(Animator animation) {
transitionDone.set(true);
if (previousFragment != null) {
previousFragment.didDisappear();
}
didAppear();
}
});
}
} else if (hideTransitionAnimationIds.contains(nextAnim)) {
animator = AnimatorInflater.loadAnimator(getActivity(), nextAnim);
if (animator != null && !enter) {
animator.addListener(new TransitionAnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
if (previousFragment != null) {
previousFragment.willAppear();
}
willDisappear();
}
@Override
public void onAnimationEnd(Animator animation) {
if (previousFragment != null) {
previousFragment.didAppear();
}
didDisappear();
}
});
}
}
Я использую этот метод для загрузки модели:
protected void waitForTransition() {
if (transitionDone != null) {
try {
transitionDone.get();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Что обычно помогает мне "подождать", пока анимация не закончится, прежде чем я загружу свои модели. Я думал, что это проблема.
Моя цель - сгладить анимацию. Мне известен трюк «предоставить изображение» (перефразировать), показанный в этом вопросе: Вложенные фрагменты исчезают во время анимации перехода , но я искал что-то немного чище. Я думал, что может быть возможность создать два фрагмента на лету? Т.е.: у меня есть пустой макет с 2 frameLayout, в который я мог бы просто вставить два фрагмента во время выполнения. Хотя я этого не пробовал, он не выглядит очень модульным.