mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-05-06 00:03:23 +08:00
Trigger transition finish event from native stack (#330)
This change adds new event that gets dispatched from native stack when screen transitioning is finished. The new event is used by react-navigation to update the library internal state that the triggered action has been finished. Previously we were relying solely on onAppear and onDisappear events, however those does not get triggered when new iOS 13 modals are used or when transparent modals are displayed. This is because with transparent modals the view below is still visible. We therefore needed another way of notifying the library that screen transition have finished despite the fact that disappear event couldn't be triggered. As a part of this change I also refactored invalid ref cycle-break code on iOS which was ought to remove reference cycle between view and view controller. This code have been moved to viewWillDisappear callback. Also on Android part small refactoring has been done and we removed the necessity to keep mActiveScreens array which was occasionally getting out of sync with the list of active fragments.
This commit is contained in:
committed by
GitHub
parent
24b70abd64
commit
102880c18b
@@ -1,13 +1,17 @@
|
||||
package com.swmansion.rnscreens;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewParent;
|
||||
import android.view.animation.Animation;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout;
|
||||
@@ -18,6 +22,27 @@ import com.google.android.material.appbar.AppBarLayout;
|
||||
|
||||
public class ScreenStackFragment extends ScreenFragment {
|
||||
|
||||
private static class NotifyingCoordinatorLayout extends CoordinatorLayout {
|
||||
|
||||
private final ScreenFragment mFragment;
|
||||
|
||||
public NotifyingCoordinatorLayout(@NonNull Context context, ScreenFragment fragment) {
|
||||
super(context);
|
||||
mFragment = fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startAnimation(Animation animation) {
|
||||
super.startAnimation(animation);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAnimationEnd() {
|
||||
super.onAnimationEnd();
|
||||
mFragment.onViewAnimationEnd();
|
||||
}
|
||||
}
|
||||
|
||||
private static final float TOOLBAR_ELEVATION = PixelUtil.toPixelFromDIP(4);
|
||||
|
||||
private AppBarLayout mAppBarLayout;
|
||||
@@ -62,7 +87,7 @@ public class ScreenStackFragment extends ScreenFragment {
|
||||
}
|
||||
|
||||
private CoordinatorLayout configureView() {
|
||||
CoordinatorLayout view = new CoordinatorLayout(getContext());
|
||||
CoordinatorLayout view = new NotifyingCoordinatorLayout(getContext(), this);
|
||||
CoordinatorLayout.LayoutParams params = new CoordinatorLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
|
||||
params.setBehavior(new AppBarLayout.ScrollingViewBehavior());
|
||||
@@ -86,6 +111,30 @@ public class ScreenStackFragment extends ScreenFragment {
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewAnimationEnd() {
|
||||
super.onViewAnimationEnd();
|
||||
notifyViewAppearTransitionEnd();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
|
||||
if (enter && transit == 0) {
|
||||
// this means that the fragment will appear without transition, in this case onViewAnimationEnd
|
||||
// won't be called and we need to notify stack directly from here.
|
||||
notifyViewAppearTransitionEnd();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void notifyViewAppearTransitionEnd() {
|
||||
ViewParent screenStack = getView().getParent();
|
||||
if (screenStack instanceof ScreenStack) {
|
||||
((ScreenStack) screenStack).onViewAppearTransitionEnd();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater,
|
||||
@Nullable ViewGroup container,
|
||||
|
||||
Reference in New Issue
Block a user