mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-04-29 21:05:29 +08:00
Fix header rendering – layout and transparency (#184)
* Let UINavController control subcontroller view's frames. This PR changes the way we've been handling yoga <> NavController layout interactions. Now we ignore frame updates coming from react for the main Screen view to allow NavController take the controll. In order to keep yoga working we now use `setSize` to pass the dimensions of the view back to yoga such that it can properly calculate layout of the views under Screen component. * Header resizing fixes for Android. In this change we use CoordinatorLayout as a stack screen container to handle rendering of toolbar and screen content. Thanks to this approach we can support collapsable bars in the future. Instead of relying on RN to layout screen container when renered under ScreenStack we rely on Android native layout to measure and position screen content and then use UIManager.setNodeSize to communicate that back to react.
This commit is contained in:
committed by
GitHub
parent
c590283359
commit
4a9a3a877a
@@ -8,7 +8,7 @@
|
|||||||
android:name=".MainApplication"
|
android:name=".MainApplication"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:networkSecurityConfig="@xml/network_security_config"
|
android:usesCleartextTraffic="true"
|
||||||
android:allowBackup="false"
|
android:allowBackup="false"
|
||||||
android:theme="@style/AppTheme">
|
android:theme="@style/AppTheme">
|
||||||
<activity
|
<activity
|
||||||
|
|||||||
@@ -48,7 +48,9 @@ repositories {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation 'com.facebook.react:react-native:+'
|
implementation 'com.facebook.react:react-native:+'
|
||||||
implementation 'androidx.appcompat:appcompat:1.1.0-rc01'
|
implementation 'androidx.appcompat:appcompat:1.1.0'
|
||||||
|
implementation 'androidx.coordinatorlayout:coordinatorlayout:1.0.0'
|
||||||
|
implementation 'com.google.android.material:material:1.0.0'
|
||||||
}
|
}
|
||||||
|
|
||||||
def configureReactNativePom(def pom) {
|
def configureReactNativePom(def pom) {
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
package com.swmansion.rnscreens;
|
package com.swmansion.rnscreens;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.os.Bundle;
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.inputmethod.InputMethodManager;
|
import android.view.inputmethod.InputMethodManager;
|
||||||
@@ -13,11 +11,12 @@ import android.widget.TextView;
|
|||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
|
|
||||||
|
import com.facebook.react.bridge.GuardedRunnable;
|
||||||
import com.facebook.react.bridge.ReactContext;
|
import com.facebook.react.bridge.ReactContext;
|
||||||
|
import com.facebook.react.uimanager.MeasureSpecAssertions;
|
||||||
import com.facebook.react.uimanager.PointerEvents;
|
import com.facebook.react.uimanager.PointerEvents;
|
||||||
import com.facebook.react.uimanager.ReactPointerEventsView;
|
import com.facebook.react.uimanager.ReactPointerEventsView;
|
||||||
import com.facebook.react.uimanager.UIManagerModule;
|
import com.facebook.react.uimanager.UIManagerModule;
|
||||||
import com.facebook.react.uimanager.events.EventDispatcher;
|
|
||||||
|
|
||||||
public class Screen extends ViewGroup implements ReactPointerEventsView {
|
public class Screen extends ViewGroup implements ReactPointerEventsView {
|
||||||
|
|
||||||
@@ -33,34 +32,6 @@ public class Screen extends ViewGroup implements ReactPointerEventsView {
|
|||||||
FADE
|
FADE
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ScreenFragment extends Fragment {
|
|
||||||
|
|
||||||
private Screen mScreenView;
|
|
||||||
|
|
||||||
public ScreenFragment() {
|
|
||||||
throw new IllegalStateException("Screen fragments should never be restored");
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("ValidFragment")
|
|
||||||
public ScreenFragment(Screen screenView) {
|
|
||||||
super();
|
|
||||||
mScreenView = screenView;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View onCreateView(LayoutInflater inflater,
|
|
||||||
@Nullable ViewGroup container,
|
|
||||||
@Nullable Bundle savedInstanceState) {
|
|
||||||
return mScreenView;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDestroy() {
|
|
||||||
super.onDestroy();
|
|
||||||
mScreenView.mEventDispatcher.dispatchEvent(new ScreenDismissedEvent(mScreenView.getId()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static OnAttachStateChangeListener sShowSoftKeyboardOnAttach = new OnAttachStateChangeListener() {
|
private static OnAttachStateChangeListener sShowSoftKeyboardOnAttach = new OnAttachStateChangeListener() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -77,8 +48,7 @@ public class Screen extends ViewGroup implements ReactPointerEventsView {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private final Fragment mFragment;
|
private @Nullable Fragment mFragment;
|
||||||
private final EventDispatcher mEventDispatcher;
|
|
||||||
private @Nullable ScreenContainer mContainer;
|
private @Nullable ScreenContainer mContainer;
|
||||||
private boolean mActive;
|
private boolean mActive;
|
||||||
private boolean mTransitioning;
|
private boolean mTransitioning;
|
||||||
@@ -87,13 +57,23 @@ public class Screen extends ViewGroup implements ReactPointerEventsView {
|
|||||||
|
|
||||||
public Screen(ReactContext context) {
|
public Screen(ReactContext context) {
|
||||||
super(context);
|
super(context);
|
||||||
mFragment = new ScreenFragment(this);
|
|
||||||
mEventDispatcher = context.getNativeModule(UIManagerModule.class).getEventDispatcher();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onLayout(boolean changed, int l, int t, int b, int r) {
|
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||||
// no-op
|
if (changed) {
|
||||||
|
final int width = r - l;
|
||||||
|
final int height = b - t;
|
||||||
|
final ReactContext reactContext = (ReactContext) getContext();
|
||||||
|
reactContext.runOnNativeModulesQueueThread(
|
||||||
|
new GuardedRunnable(reactContext) {
|
||||||
|
@Override
|
||||||
|
public void runGuarded() {
|
||||||
|
reactContext.getNativeModule(UIManagerModule.class)
|
||||||
|
.updateNodeSize(getId(), width, height);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -166,14 +146,18 @@ public class Screen extends ViewGroup implements ReactPointerEventsView {
|
|||||||
mContainer = container;
|
mContainer = container;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected @Nullable ScreenContainer getContainer() {
|
protected void setFragment(Fragment fragment) {
|
||||||
return mContainer;
|
mFragment = fragment;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Fragment getFragment() {
|
protected @Nullable Fragment getFragment() {
|
||||||
return mFragment;
|
return mFragment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected @Nullable ScreenContainer getContainer() {
|
||||||
|
return mContainer;
|
||||||
|
}
|
||||||
|
|
||||||
public void setActive(boolean active) {
|
public void setActive(boolean active) {
|
||||||
if (active == mActive) {
|
if (active == mActive) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import android.view.ViewGroup;
|
|||||||
import android.view.ViewParent;
|
import android.view.ViewParent;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
import androidx.fragment.app.FragmentActivity;
|
import androidx.fragment.app.FragmentActivity;
|
||||||
import androidx.fragment.app.FragmentTransaction;
|
import androidx.fragment.app.FragmentTransaction;
|
||||||
|
|
||||||
@@ -16,13 +15,12 @@ import com.facebook.react.modules.core.ReactChoreographer;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public class ScreenContainer extends ViewGroup {
|
public class ScreenContainer<T extends ScreenFragment> extends ViewGroup {
|
||||||
|
|
||||||
protected final ArrayList<Screen> mScreens = new ArrayList<>();
|
protected final ArrayList<T> mScreenFragments = new ArrayList<>();
|
||||||
private final Set<Screen> mActiveScreens = new HashSet<>();
|
private final Set<ScreenFragment> mActiveScreenFragments = new HashSet<>();
|
||||||
|
|
||||||
private @Nullable FragmentTransaction mCurrentTransaction;
|
private @Nullable FragmentTransaction mCurrentTransaction;
|
||||||
private boolean mNeedUpdate;
|
private boolean mNeedUpdate;
|
||||||
@@ -59,24 +57,30 @@ public class ScreenContainer extends ViewGroup {
|
|||||||
markUpdated();
|
markUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected T adapt(Screen screen) {
|
||||||
|
return (T) new ScreenFragment(screen);
|
||||||
|
}
|
||||||
|
|
||||||
protected void addScreen(Screen screen, int index) {
|
protected void addScreen(Screen screen, int index) {
|
||||||
mScreens.add(index, screen);
|
T fragment = adapt(screen);
|
||||||
|
screen.setFragment(fragment);
|
||||||
|
mScreenFragments.add(index, fragment);
|
||||||
screen.setContainer(this);
|
screen.setContainer(this);
|
||||||
markUpdated();
|
markUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void removeScreenAt(int index) {
|
protected void removeScreenAt(int index) {
|
||||||
mScreens.get(index).setContainer(null);
|
mScreenFragments.get(index).getScreen().setContainer(null);
|
||||||
mScreens.remove(index);
|
mScreenFragments.remove(index);
|
||||||
markUpdated();
|
markUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int getScreenCount() {
|
protected int getScreenCount() {
|
||||||
return mScreens.size();
|
return mScreenFragments.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Screen getScreenAt(int index) {
|
protected Screen getScreenAt(int index) {
|
||||||
return mScreens.get(index);
|
return mScreenFragments.get(index).getScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final FragmentActivity findRootFragmentActivity() {
|
protected final FragmentActivity findRootFragmentActivity() {
|
||||||
@@ -120,25 +124,24 @@ public class ScreenContainer extends ViewGroup {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void attachScreen(Screen screen) {
|
private void attachScreen(ScreenFragment screenFragment) {
|
||||||
getOrCreateTransaction().add(getId(), screen.getFragment());
|
getOrCreateTransaction().add(getId(), screenFragment);
|
||||||
mActiveScreens.add(screen);
|
mActiveScreenFragments.add(screenFragment);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void moveToFront(Screen screen) {
|
private void moveToFront(ScreenFragment screenFragment) {
|
||||||
FragmentTransaction transaction = getOrCreateTransaction();
|
FragmentTransaction transaction = getOrCreateTransaction();
|
||||||
Fragment fragment = screen.getFragment();
|
transaction.remove(screenFragment);
|
||||||
transaction.remove(fragment);
|
transaction.add(getId(), screenFragment);
|
||||||
transaction.add(getId(), fragment);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void detachScreen(Screen screen) {
|
private void detachScreen(ScreenFragment screenFragment) {
|
||||||
getOrCreateTransaction().remove(screen.getFragment());
|
getOrCreateTransaction().remove(screenFragment);
|
||||||
mActiveScreens.remove(screen);
|
mActiveScreenFragments.remove(screenFragment);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isScreenActive(Screen screen, List<Screen> allScreens) {
|
protected boolean isScreenActive(ScreenFragment screenFragment) {
|
||||||
return screen.isActive();
|
return screenFragment.getScreen().isActive();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -164,26 +167,26 @@ public class ScreenContainer extends ViewGroup {
|
|||||||
|
|
||||||
protected void onUpdate() {
|
protected void onUpdate() {
|
||||||
// detach screens that are no longer active
|
// detach screens that are no longer active
|
||||||
Set<Screen> orphaned = new HashSet<>(mActiveScreens);
|
Set<ScreenFragment> orphaned = new HashSet<>(mActiveScreenFragments);
|
||||||
for (int i = 0, size = mScreens.size(); i < size; i++) {
|
for (int i = 0, size = mScreenFragments.size(); i < size; i++) {
|
||||||
Screen screen = mScreens.get(i);
|
ScreenFragment screenFragment = mScreenFragments.get(i);
|
||||||
boolean isActive = isScreenActive(screen, mScreens);
|
boolean isActive = isScreenActive(screenFragment);
|
||||||
if (!isActive && mActiveScreens.contains(screen)) {
|
if (!isActive && mActiveScreenFragments.contains(screenFragment)) {
|
||||||
detachScreen(screen);
|
detachScreen(screenFragment);
|
||||||
}
|
}
|
||||||
orphaned.remove(screen);
|
orphaned.remove(screenFragment);
|
||||||
}
|
}
|
||||||
if (!orphaned.isEmpty()) {
|
if (!orphaned.isEmpty()) {
|
||||||
Object[] orphanedAry = orphaned.toArray();
|
Object[] orphanedAry = orphaned.toArray();
|
||||||
for (int i = 0; i < orphanedAry.length; i++) {
|
for (int i = 0; i < orphanedAry.length; i++) {
|
||||||
detachScreen((Screen) orphanedAry[i]);
|
detachScreen((ScreenFragment) orphanedAry[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// detect if we are "transitioning" based on the number of active screens
|
// detect if we are "transitioning" based on the number of active screens
|
||||||
int activeScreens = 0;
|
int activeScreens = 0;
|
||||||
for (int i = 0, size = mScreens.size(); i < size; i++) {
|
for (int i = 0, size = mScreenFragments.size(); i < size; i++) {
|
||||||
if (isScreenActive(mScreens.get(i), mScreens)) {
|
if (isScreenActive(mScreenFragments.get(i))) {
|
||||||
activeScreens += 1;
|
activeScreens += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -191,16 +194,16 @@ public class ScreenContainer extends ViewGroup {
|
|||||||
|
|
||||||
// attach newly activated screens
|
// attach newly activated screens
|
||||||
boolean addedBefore = false;
|
boolean addedBefore = false;
|
||||||
for (int i = 0, size = mScreens.size(); i < size; i++) {
|
for (int i = 0, size = mScreenFragments.size(); i < size; i++) {
|
||||||
Screen screen = mScreens.get(i);
|
ScreenFragment screenFragment = mScreenFragments.get(i);
|
||||||
boolean isActive = isScreenActive(screen, mScreens);
|
boolean isActive = isScreenActive(screenFragment);
|
||||||
if (isActive && !mActiveScreens.contains(screen)) {
|
if (isActive && !mActiveScreenFragments.contains(screenFragment)) {
|
||||||
addedBefore = true;
|
addedBefore = true;
|
||||||
attachScreen(screen);
|
attachScreen(screenFragment);
|
||||||
} else if (isActive && addedBefore) {
|
} else if (isActive && addedBefore) {
|
||||||
moveToFront(screen);
|
moveToFront(screenFragment);
|
||||||
}
|
}
|
||||||
screen.setTransitioning(transitioning);
|
screenFragment.getScreen().setTransitioning(transitioning);
|
||||||
}
|
}
|
||||||
tryCommitTransaction();
|
tryCommitTransaction();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
package com.swmansion.rnscreens;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.appcompat.widget.Toolbar;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
|
||||||
|
import com.facebook.react.bridge.ReactContext;
|
||||||
|
import com.facebook.react.uimanager.UIManagerModule;
|
||||||
|
import com.facebook.react.uimanager.events.EventDispatcher;
|
||||||
|
|
||||||
|
public class ScreenFragment extends Fragment {
|
||||||
|
|
||||||
|
protected Screen mScreenView;
|
||||||
|
|
||||||
|
public ScreenFragment() {
|
||||||
|
throw new IllegalStateException("Screen fragments should never be restored");
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("ValidFragment")
|
||||||
|
public ScreenFragment(Screen screenView) {
|
||||||
|
super();
|
||||||
|
mScreenView = screenView;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater,
|
||||||
|
@Nullable ViewGroup container,
|
||||||
|
@Nullable Bundle savedInstanceState) {
|
||||||
|
return mScreenView;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Screen getScreen() {
|
||||||
|
return mScreenView;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
((ReactContext) mScreenView.getContext())
|
||||||
|
.getNativeModule(UIManagerModule.class)
|
||||||
|
.getEventDispatcher()
|
||||||
|
.dispatchEvent(new ScreenDismissedEvent(mScreenView.getId()));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,42 +8,76 @@ import java.util.ArrayList;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public class ScreenStack extends ScreenContainer {
|
public class ScreenStack extends ScreenContainer<ScreenStackFragment> {
|
||||||
|
|
||||||
private final ArrayList<Screen> mStack = new ArrayList<>();
|
private final ArrayList<ScreenStackFragment> mStack = new ArrayList<>();
|
||||||
private final Set<Screen> mDismissed = new HashSet<>();
|
private final Set<ScreenStackFragment> mDismissed = new HashSet<>();
|
||||||
|
|
||||||
private Screen mTopScreen = null;
|
private ScreenStackFragment mTopScreen = null;
|
||||||
|
private boolean mLayoutEnqueued = false;
|
||||||
|
|
||||||
public ScreenStack(Context context) {
|
public ScreenStack(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void dismiss(Screen screen) {
|
public void dismiss(ScreenStackFragment screenFragment) {
|
||||||
mDismissed.add(screen);
|
mDismissed.add(screenFragment);
|
||||||
onUpdate();
|
onUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Screen getTopScreen() {
|
|
||||||
for (int i = getScreenCount() - 1; i >= 0; i--) {
|
|
||||||
Screen screen = getScreenAt(i);
|
|
||||||
if (!mDismissed.contains(screen)) {
|
|
||||||
return screen;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new IllegalStateException("Stack is empty");
|
|
||||||
}
|
|
||||||
|
|
||||||
public Screen getRootScreen() {
|
public Screen getRootScreen() {
|
||||||
for (int i = 0, size = getScreenCount(); i < size; i++) {
|
for (int i = 0, size = getScreenCount(); i < size; i++) {
|
||||||
Screen screen = getScreenAt(i);
|
Screen screen = getScreenAt(i);
|
||||||
if (!mDismissed.contains(screen)) {
|
if (!mDismissed.contains(screen.getFragment())) {
|
||||||
return screen;
|
return screen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new IllegalStateException("Stack has no root screen set");
|
throw new IllegalStateException("Stack has no root screen set");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ScreenStackFragment adapt(Screen screen) {
|
||||||
|
return new ScreenStackFragment(screen);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||||
|
for (int i = 0, size = getChildCount(); i < size; i++) {
|
||||||
|
getChildAt(i).layout(0, 0, getWidth(), getHeight());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||||
|
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||||
|
for (int i = 0, size = getChildCount(); i < size; i++) {
|
||||||
|
getChildAt(i).measure(
|
||||||
|
MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.EXACTLY),
|
||||||
|
MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.EXACTLY));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Runnable mLayoutRunnable = new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mLayoutEnqueued = false;
|
||||||
|
measure(
|
||||||
|
MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.EXACTLY),
|
||||||
|
MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.EXACTLY));
|
||||||
|
layout(getLeft(), getTop(), getRight(), getBottom());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void requestLayout() {
|
||||||
|
super.requestLayout();
|
||||||
|
|
||||||
|
if (!mLayoutEnqueued) {
|
||||||
|
mLayoutEnqueued = true;
|
||||||
|
post(mLayoutRunnable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void removeScreenAt(int index) {
|
protected void removeScreenAt(int index) {
|
||||||
Screen toBeRemoved = getScreenAt(index);
|
Screen toBeRemoved = getScreenAt(index);
|
||||||
@@ -54,20 +88,20 @@ public class ScreenStack extends ScreenContainer {
|
|||||||
@Override
|
@Override
|
||||||
protected void onUpdate() {
|
protected void onUpdate() {
|
||||||
// remove all screens previously on stack
|
// remove all screens previously on stack
|
||||||
for (Screen screen : mStack) {
|
for (ScreenStackFragment screen : mStack) {
|
||||||
if (!mScreens.contains(screen) || mDismissed.contains(screen)) {
|
if (!mScreenFragments.contains(screen) || mDismissed.contains(screen)) {
|
||||||
getOrCreateTransaction().remove(screen.getFragment());
|
getOrCreateTransaction().remove(screen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Screen newTop = null;
|
ScreenStackFragment newTop = null;
|
||||||
Screen belowTop = null; // this is only set if newTop has TRANSPARENT_MODAL presentation mode
|
ScreenStackFragment belowTop = null; // this is only set if newTop has TRANSPARENT_MODAL presentation mode
|
||||||
|
|
||||||
for (int i = mScreens.size() - 1; i >= 0; i--) {
|
for (int i = mScreenFragments.size() - 1; i >= 0; i--) {
|
||||||
Screen screen = mScreens.get(i);
|
ScreenStackFragment screen = mScreenFragments.get(i);
|
||||||
if (!mDismissed.contains(screen)) {
|
if (!mDismissed.contains(screen)) {
|
||||||
if (newTop == null) {
|
if (newTop == null) {
|
||||||
newTop = screen;
|
newTop = screen;
|
||||||
if (newTop.getStackPresentation() != Screen.StackPresentation.TRANSPARENT_MODAL) {
|
if (newTop.getScreen().getStackPresentation() != Screen.StackPresentation.TRANSPARENT_MODAL) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -78,34 +112,34 @@ public class ScreenStack extends ScreenContainer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (Screen screen : mScreens) {
|
for (ScreenStackFragment screen : mScreenFragments) {
|
||||||
// add all new views that weren't on stack before
|
// add all new views that weren't on stack before
|
||||||
if (!mStack.contains(screen) && !mDismissed.contains(screen)) {
|
if (!mStack.contains(screen) && !mDismissed.contains(screen)) {
|
||||||
getOrCreateTransaction().add(getId(), screen.getFragment());
|
getOrCreateTransaction().add(getId(), screen);
|
||||||
}
|
}
|
||||||
// detach all screens that should not be visible
|
// detach all screens that should not be visible
|
||||||
if (screen != newTop && screen != belowTop && !mDismissed.contains(screen)) {
|
if (screen != newTop && screen != belowTop && !mDismissed.contains(screen)) {
|
||||||
getOrCreateTransaction().hide(screen.getFragment());
|
getOrCreateTransaction().hide(screen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// attach "below top" screen if set
|
// attach "below top" screen if set
|
||||||
if (belowTop != null) {
|
if (belowTop != null) {
|
||||||
final Screen top = newTop;
|
final ScreenStackFragment top = newTop;
|
||||||
getOrCreateTransaction().show(belowTop.getFragment()).runOnCommit(new Runnable() {
|
getOrCreateTransaction().show(belowTop).runOnCommit(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
top.bringToFront();
|
top.getScreen().bringToFront();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
getOrCreateTransaction().show(newTop.getFragment());
|
getOrCreateTransaction().show(newTop);
|
||||||
|
|
||||||
if (!mStack.contains(newTop)) {
|
if (!mStack.contains(newTop)) {
|
||||||
// if new top screen wasn't on stack we do "open animation" so long it is not the very first screen on stack
|
// if new top screen wasn't on stack we do "open animation" so long it is not the very first screen on stack
|
||||||
if (mTopScreen != null) {
|
if (mTopScreen != null) {
|
||||||
// there was some other screen attached before
|
// there was some other screen attached before
|
||||||
int transition = FragmentTransaction.TRANSIT_FRAGMENT_OPEN;
|
int transition = FragmentTransaction.TRANSIT_FRAGMENT_OPEN;
|
||||||
switch (mTopScreen.getStackAnimation()) {
|
switch (mTopScreen.getScreen().getStackAnimation()) {
|
||||||
case NONE:
|
case NONE:
|
||||||
transition = FragmentTransaction.TRANSIT_NONE;
|
transition = FragmentTransaction.TRANSIT_NONE;
|
||||||
break;
|
break;
|
||||||
@@ -118,7 +152,7 @@ public class ScreenStack extends ScreenContainer {
|
|||||||
} else if (mTopScreen != null && !mTopScreen.equals(newTop)) {
|
} else if (mTopScreen != null && !mTopScreen.equals(newTop)) {
|
||||||
// otherwise if we are performing top screen change we do "back animation"
|
// otherwise if we are performing top screen change we do "back animation"
|
||||||
int transition = FragmentTransaction.TRANSIT_FRAGMENT_CLOSE;
|
int transition = FragmentTransaction.TRANSIT_FRAGMENT_CLOSE;
|
||||||
switch (mTopScreen.getStackAnimation()) {
|
switch (mTopScreen.getScreen().getStackAnimation()) {
|
||||||
case NONE:
|
case NONE:
|
||||||
transition = FragmentTransaction.TRANSIT_NONE;
|
transition = FragmentTransaction.TRANSIT_NONE;
|
||||||
break;
|
break;
|
||||||
@@ -132,7 +166,7 @@ public class ScreenStack extends ScreenContainer {
|
|||||||
mTopScreen = newTop;
|
mTopScreen = newTop;
|
||||||
|
|
||||||
mStack.clear();
|
mStack.clear();
|
||||||
mStack.addAll(mScreens);
|
mStack.addAll(mScreenFragments);
|
||||||
|
|
||||||
tryCommitTransaction();
|
tryCommitTransaction();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,82 @@
|
|||||||
|
package com.swmansion.rnscreens;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.appcompat.widget.Toolbar;
|
||||||
|
import androidx.coordinatorlayout.widget.CoordinatorLayout;
|
||||||
|
|
||||||
|
import com.facebook.react.uimanager.PixelUtil;
|
||||||
|
import com.google.android.material.appbar.AppBarLayout;
|
||||||
|
|
||||||
|
public class ScreenStackFragment extends ScreenFragment {
|
||||||
|
|
||||||
|
private static final float TOOLBAR_ELEVATION = PixelUtil.toPixelFromDIP(4);
|
||||||
|
|
||||||
|
private AppBarLayout mAppBarLayout;
|
||||||
|
private Toolbar mToolbar;
|
||||||
|
private boolean mShadowHidden;
|
||||||
|
|
||||||
|
@SuppressLint("ValidFragment")
|
||||||
|
public ScreenStackFragment(Screen screenView) {
|
||||||
|
super(screenView);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeToolbar() {
|
||||||
|
if (mAppBarLayout != null) {
|
||||||
|
((CoordinatorLayout) getView()).removeView(mAppBarLayout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setToolbar(Toolbar toolbar) {
|
||||||
|
if (mAppBarLayout != null) {
|
||||||
|
mAppBarLayout.addView(toolbar);
|
||||||
|
}
|
||||||
|
mToolbar = toolbar;
|
||||||
|
AppBarLayout.LayoutParams params = new AppBarLayout.LayoutParams(
|
||||||
|
AppBarLayout.LayoutParams.MATCH_PARENT, AppBarLayout.LayoutParams.WRAP_CONTENT);
|
||||||
|
params.setScrollFlags(0);
|
||||||
|
mToolbar.setLayoutParams(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setToolbarShadowHidden(boolean hidden) {
|
||||||
|
if (mShadowHidden != hidden) {
|
||||||
|
mAppBarLayout.setTargetElevation(hidden ? 0 : TOOLBAR_ELEVATION);
|
||||||
|
mShadowHidden = hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater,
|
||||||
|
@Nullable ViewGroup container,
|
||||||
|
@Nullable Bundle savedInstanceState) {
|
||||||
|
CoordinatorLayout view = new CoordinatorLayout(getContext());
|
||||||
|
CoordinatorLayout.LayoutParams params = new CoordinatorLayout.LayoutParams(
|
||||||
|
LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
|
||||||
|
params.setBehavior(new AppBarLayout.ScrollingViewBehavior());
|
||||||
|
mScreenView.setLayoutParams(params);
|
||||||
|
view.addView(mScreenView);
|
||||||
|
|
||||||
|
mAppBarLayout = new AppBarLayout(getContext());
|
||||||
|
// By default AppBarLayout will have a background color set but since we cover the whole layout
|
||||||
|
// with toolbar (that can be semi-transparent) the bar layout background color does not pay a
|
||||||
|
// role. On top of that it breaks screens animations when alfa offscreen compositing is off
|
||||||
|
// (which is the default)
|
||||||
|
mAppBarLayout.setBackgroundColor(Color.TRANSPARENT);
|
||||||
|
mAppBarLayout.setLayoutParams(new AppBarLayout.LayoutParams(
|
||||||
|
AppBarLayout.LayoutParams.MATCH_PARENT, AppBarLayout.LayoutParams.WRAP_CONTENT));
|
||||||
|
view.addView(mAppBarLayout);
|
||||||
|
|
||||||
|
if (mToolbar != null) {
|
||||||
|
mAppBarLayout.addView(mToolbar);
|
||||||
|
}
|
||||||
|
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.swmansion.rnscreens;
|
package com.swmansion.rnscreens;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.graphics.Color;
|
||||||
import android.graphics.PorterDuff;
|
import android.graphics.PorterDuff;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.util.TypedValue;
|
import android.util.TypedValue;
|
||||||
@@ -16,42 +17,10 @@ import androidx.appcompat.app.AppCompatActivity;
|
|||||||
import androidx.appcompat.widget.Toolbar;
|
import androidx.appcompat.widget.Toolbar;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
|
|
||||||
import com.facebook.react.uimanager.PixelUtil;
|
|
||||||
import com.facebook.react.views.text.ReactFontManager;
|
import com.facebook.react.views.text.ReactFontManager;
|
||||||
|
|
||||||
public class ScreenStackHeaderConfig extends ViewGroup {
|
public class ScreenStackHeaderConfig extends ViewGroup {
|
||||||
|
|
||||||
private static final float TOOLBAR_ELEVATION = PixelUtil.toPixelFromDIP(4);
|
|
||||||
|
|
||||||
private static final class ToolbarWithLayoutLoop extends Toolbar {
|
|
||||||
|
|
||||||
private final Runnable mLayoutRunnable = new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
mLayoutEnqueued = false;
|
|
||||||
measure(
|
|
||||||
MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.EXACTLY),
|
|
||||||
MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.EXACTLY));
|
|
||||||
layout(getLeft(), getTop(), getRight(), getBottom());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
private boolean mLayoutEnqueued = false;
|
|
||||||
|
|
||||||
public ToolbarWithLayoutLoop(Context context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void requestLayout() {
|
|
||||||
super.requestLayout();
|
|
||||||
|
|
||||||
if (!mLayoutEnqueued) {
|
|
||||||
mLayoutEnqueued = true;
|
|
||||||
post(mLayoutRunnable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final ScreenStackHeaderSubview mConfigSubviews[] = new ScreenStackHeaderSubview[3];
|
private final ScreenStackHeaderSubview mConfigSubviews[] = new ScreenStackHeaderSubview[3];
|
||||||
private int mSubviewsCount = 0;
|
private int mSubviewsCount = 0;
|
||||||
private String mTitle;
|
private String mTitle;
|
||||||
@@ -63,20 +32,18 @@ public class ScreenStackHeaderConfig extends ViewGroup {
|
|||||||
private boolean mIsBackButtonHidden;
|
private boolean mIsBackButtonHidden;
|
||||||
private boolean mIsShadowHidden;
|
private boolean mIsShadowHidden;
|
||||||
private int mTintColor;
|
private int mTintColor;
|
||||||
private int mWidth;
|
|
||||||
private int mHeight;
|
|
||||||
private final Toolbar mToolbar;
|
private final Toolbar mToolbar;
|
||||||
|
|
||||||
private OnBackPressedCallback mBackCallback = new OnBackPressedCallback(false) {
|
private OnBackPressedCallback mBackCallback = new OnBackPressedCallback(false) {
|
||||||
@Override
|
@Override
|
||||||
public void handleOnBackPressed() {
|
public void handleOnBackPressed() {
|
||||||
getScreenStack().dismiss(getScreen());
|
getScreenStack().dismiss(getScreenFragment());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
private OnClickListener mBackClickListener = new OnClickListener() {
|
private OnClickListener mBackClickListener = new OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
getScreenStack().dismiss(getScreen());
|
getScreenStack().dismiss(getScreenFragment());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -84,36 +51,18 @@ public class ScreenStackHeaderConfig extends ViewGroup {
|
|||||||
super(context);
|
super(context);
|
||||||
setVisibility(View.GONE);
|
setVisibility(View.GONE);
|
||||||
|
|
||||||
mToolbar = new ToolbarWithLayoutLoop(context);
|
mToolbar = new Toolbar(context);
|
||||||
|
|
||||||
// set primary color as background by default
|
// set primary color as background by default
|
||||||
TypedValue tv = new TypedValue();
|
TypedValue tv = new TypedValue();
|
||||||
if (context.getTheme().resolveAttribute(android.R.attr.colorPrimary, tv, true)) {
|
if (context.getTheme().resolveAttribute(android.R.attr.colorPrimary, tv, true)) {
|
||||||
mToolbar.setBackgroundColor(tv.data);
|
mToolbar.setBackgroundColor(tv.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
mWidth = 0;
|
|
||||||
mHeight = 0;
|
|
||||||
|
|
||||||
if (context.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) {
|
|
||||||
mHeight = TypedValue.complexToDimensionPixelSize(tv.data, getResources().getDisplayMetrics());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateToolbarLayout() {
|
|
||||||
mToolbar.measure(
|
|
||||||
View.MeasureSpec.makeMeasureSpec(mWidth, View.MeasureSpec.EXACTLY),
|
|
||||||
View.MeasureSpec.makeMeasureSpec(mHeight, View.MeasureSpec.EXACTLY));
|
|
||||||
mToolbar.layout(0, 0, mWidth, mHeight);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||||
if (mWidth != (r - l)) {
|
// no-op
|
||||||
mWidth = (r - l);
|
|
||||||
updateToolbarLayout();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -141,10 +90,13 @@ public class ScreenStackHeaderConfig extends ViewGroup {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Fragment getScreenFragment() {
|
private ScreenStackFragment getScreenFragment() {
|
||||||
ViewParent screen = getParent();
|
ViewParent screen = getParent();
|
||||||
if (screen instanceof Screen) {
|
if (screen instanceof Screen) {
|
||||||
return ((Screen) screen).getFragment();
|
Fragment fragment = ((Screen) screen).getFragment();
|
||||||
|
if (fragment instanceof ScreenStackFragment) {
|
||||||
|
return (ScreenStackFragment) fragment;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -159,16 +111,16 @@ public class ScreenStackHeaderConfig extends ViewGroup {
|
|||||||
Screen parent = (Screen) getParent();
|
Screen parent = (Screen) getParent();
|
||||||
if (mIsHidden) {
|
if (mIsHidden) {
|
||||||
if (mToolbar.getParent() != null) {
|
if (mToolbar.getParent() != null) {
|
||||||
parent.removeView(mToolbar);
|
getScreenFragment().removeToolbar();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mToolbar.getParent() == null) {
|
if (mToolbar.getParent() == null) {
|
||||||
parent.addView(mToolbar);
|
getScreenFragment().setToolbar(mToolbar);
|
||||||
}
|
}
|
||||||
|
|
||||||
AppCompatActivity activity = (AppCompatActivity) parent.getFragment().getActivity();
|
AppCompatActivity activity = (AppCompatActivity) getScreenFragment().getActivity();
|
||||||
activity.setSupportActionBar(mToolbar);
|
activity.setSupportActionBar(mToolbar);
|
||||||
ActionBar actionBar = activity.getSupportActionBar();
|
ActionBar actionBar = activity.getSupportActionBar();
|
||||||
|
|
||||||
@@ -188,7 +140,7 @@ public class ScreenStackHeaderConfig extends ViewGroup {
|
|||||||
|
|
||||||
|
|
||||||
// shadow
|
// shadow
|
||||||
actionBar.setElevation(mIsShadowHidden ? 0 : TOOLBAR_ELEVATION);
|
getScreenFragment().setToolbarShadowHidden(mIsShadowHidden);
|
||||||
|
|
||||||
// title
|
// title
|
||||||
actionBar.setTitle(mTitle);
|
actionBar.setTitle(mTitle);
|
||||||
|
|||||||
@@ -59,4 +59,9 @@ public class ScreenStackViewManager extends ViewGroupManager<ScreenStack> {
|
|||||||
public View getChildAt(ScreenStack parent, int index) {
|
public View getChildAt(ScreenStack parent, int index) {
|
||||||
return parent.getScreenAt(index);
|
return parent.getScreenAt(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean needsCustomLayoutForChildren() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,20 +66,15 @@
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)reactSetFrame:(CGRect)frame
|
||||||
|
{
|
||||||
|
// ignore setFrame call from react, the frame of this view
|
||||||
|
// is controlled by the UIViewController it is contained in
|
||||||
|
}
|
||||||
|
|
||||||
- (void)updateBounds
|
- (void)updateBounds
|
||||||
{
|
{
|
||||||
CGFloat navbarOffset = 0;
|
[_bridge.uiManager setSize:self.bounds.size forView:self];
|
||||||
UINavigationController *navctr = self.controller.navigationController;
|
|
||||||
if (!navctr.isNavigationBarHidden && !navctr.navigationBar.isTranslucent) {
|
|
||||||
CGRect navbarFrame = navctr.navigationBar.frame;
|
|
||||||
navbarOffset = navbarFrame.origin.y + navbarFrame.size.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
[_bridge.uiManager
|
|
||||||
setLocalData:[[RNSScreenFrameData alloc]
|
|
||||||
initWithInsets:UIEdgeInsetsZero
|
|
||||||
andNavbarOffset:navbarOffset]
|
|
||||||
forView:self];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setActive:(BOOL)active
|
- (void)setActive:(BOOL)active
|
||||||
@@ -197,6 +192,7 @@
|
|||||||
@implementation RNSScreen {
|
@implementation RNSScreen {
|
||||||
__weak UIView *_view;
|
__weak UIView *_view;
|
||||||
__weak id _previousFirstResponder;
|
__weak id _previousFirstResponder;
|
||||||
|
CGRect _lastViewFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (instancetype)initWithView:(UIView *)view
|
- (instancetype)initWithView:(UIView *)view
|
||||||
@@ -207,6 +203,16 @@
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)viewDidLayoutSubviews
|
||||||
|
{
|
||||||
|
[super viewDidLayoutSubviews];
|
||||||
|
|
||||||
|
if (!CGRectEqualToRect(_lastViewFrame, self.view.frame)) {
|
||||||
|
_lastViewFrame = self.view.frame;
|
||||||
|
[((RNSScreenView *)self.view) updateBounds];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (id)findFirstResponder:(UIView*)parent
|
- (id)findFirstResponder:(UIView*)parent
|
||||||
{
|
{
|
||||||
if (parent.isFirstResponder) {
|
if (parent.isFirstResponder) {
|
||||||
@@ -240,10 +246,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) viewDidAppear:(BOOL)animated {
|
|
||||||
[((RNSScreenView *)self.view) updateBounds];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)notifyFinishTransitioning
|
- (void)notifyFinishTransitioning
|
||||||
{
|
{
|
||||||
[_previousFirstResponder becomeFirstResponder];
|
[_previousFirstResponder becomeFirstResponder];
|
||||||
@@ -260,23 +262,6 @@
|
|||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface RNSScreenShadowView : RCTShadowView
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation RNSScreenShadowView
|
|
||||||
|
|
||||||
- (void)setLocalData:(RNSScreenFrameData *)data
|
|
||||||
{
|
|
||||||
self.paddingTop = (YGValue){data.topInset, YGUnitPoint};
|
|
||||||
self.paddingBottom = (YGValue){data.bottomInset, YGUnitPoint};
|
|
||||||
self.paddingLeft = (YGValue){data.leftInset, YGUnitPoint};
|
|
||||||
self.paddingRight = (YGValue){data.rightInset, YGUnitPoint};
|
|
||||||
self.top = (YGValue){data.navbarOffset, YGUnitPoint};
|
|
||||||
[self didSetProps:@[@"paddingTop", @"paddingBottom", @"paddingLeft", @"paddingRight", @"top"]];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation RNSScreenManager
|
@implementation RNSScreenManager
|
||||||
|
|
||||||
RCT_EXPORT_MODULE()
|
RCT_EXPORT_MODULE()
|
||||||
@@ -291,11 +276,6 @@ RCT_EXPORT_VIEW_PROPERTY(onDismissed, RCTDirectEventBlock);
|
|||||||
return [[RNSScreenView alloc] initWithBridge:self.bridge];
|
return [[RNSScreenView alloc] initWithBridge:self.bridge];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (RCTShadowView *)shadowView
|
|
||||||
{
|
|
||||||
return [RNSScreenShadowView new];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation RCTConvert (RNSScreen)
|
@implementation RCTConvert (RNSScreen)
|
||||||
|
|||||||
Reference in New Issue
Block a user