Permalink
Browse files

Fix modal size

Summary:
With our previous fix to resize the Modal on orientation change, we broke the
computation of its size. The existing computation in `ModalHostShadowNode` was
in fact correct, and we were overriding it from `onSizeChanged`. By computing the
size of the Modal in `onSizeChanged` directly (and correctly), we fix this, and
simplify code by removing the `ModalHostShadowNode`.

Reviewed By: foghina

Differential Revision: D3863054

fbshipit-source-id: aaf4a8881798df4d2ab1dab882a9d9dfdc0a9342
  • Loading branch information...
1 parent a36ccf2 commit 4941cbcf1e46047da431065e3d186d2e9c62ff6b @andreicoman11 andreicoman11 committed with Facebook Github Bot Sep 19, 2016
@@ -1,68 +0,0 @@
-/**
- * Copyright (c) 2015-present, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- */
-
-package com.facebook.react.views.modal;
-
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.graphics.Point;
-import android.view.Display;
-import android.view.Surface;
-import android.view.WindowManager;
-
-import com.facebook.csslayout.CSSNode;
-import com.facebook.react.uimanager.LayoutShadowNode;
-
-/**
- * We implement the Modal by using an Android Dialog. That will fill the entire window of the
- * application. To get layout to work properly, we need to layout all the elements within the
- * Modal's inner content view as if they can fill the entire window. To do that, we need to
- * explicitly set the styleWidth and styleHeight on the LayoutShadowNode of the child of this node
- * to be the window size. This will then cause the children of the Modal to layout as if they can
- * fill the window.
- *
- * To get that we use information from the WindowManager and default Display. We don't use
- * DisplayMetricsHolder because it returns values that include the status bar. We only want the
- * values of what will actually be shown on screen.
- */
-class ModalHostShadowNode extends LayoutShadowNode {
-
- private final Point mMinPoint = new Point();
- private final Point mMaxPoint = new Point();
-
- /**
- * We need to set the styleWidth and styleHeight of the one child (represented by the <View/>
- * within the <RCTModalHostView/> in Modal.js. This needs to fill the entire window.
- */
- @Override
- @TargetApi(16)
- public void addChildAt(CSSNode child, int i) {
- super.addChildAt(child, i);
-
- Context context = getThemedContext();
- WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
- Display display = wm.getDefaultDisplay();
- // getCurrentSizeRange will return the min and max width and height that the window can be
- display.getCurrentSizeRange(mMinPoint, mMaxPoint);
-
- int width, height;
- int rotation = display.getRotation();
- if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) {
- // If we are vertical the width value comes from min width and height comes from max height
- width = mMinPoint.x;
- height = mMaxPoint.y;
- } else {
- // If we are horizontal the width value comes from max width and height comes from min height
- width = mMaxPoint.x;
- height = mMinPoint.y;
- }
- child.setStyleWidth(width);
- child.setStyleHeight(height);
- }
-}
@@ -17,7 +17,6 @@
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.common.MapBuilder;
-import com.facebook.react.uimanager.LayoutShadowNode;
import com.facebook.react.uimanager.PixelUtil;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.UIManagerModule;
@@ -49,16 +48,6 @@ protected ReactModalHostView createViewInstance(ThemedReactContext reactContext)
}
@Override
- public LayoutShadowNode createShadowNodeInstance() {
- return new ModalHostShadowNode();
- }
-
- @Override
- public Class<? extends LayoutShadowNode> getShadowNodeClass() {
- return ModalHostShadowNode.class;
- }
-
- @Override
public void onDropViewInstance(ReactModalHostView view) {
super.onDropViewInstance(view);
view.onDropInstance();
@@ -112,8 +101,7 @@ public void onShow(DialogInterface dialog) {
0;
return MapBuilder.<String, Object>of(
- "StatusBarHeight", height
- );
+ "StatusBarHeight", height);
}
@Override
@@ -16,8 +16,11 @@
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
+import android.graphics.Point;
+import android.view.Display;
import android.view.KeyEvent;
import android.view.MotionEvent;
+import android.view.Surface;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
@@ -255,10 +258,17 @@ private void updateProperties() {
* child information forwarded from ReactModalHostView and uses that to create children. It is
* also responsible for acting as a RootView and handling touch events. It does this the same
* way as ReactRootView.
+ *
+ * To get layout to work properly, we need to layout all the elements within the Modal as if they
+ * can fill the entire window. To do that, we need to explicitly set the styleWidth and
+ * styleHeight on the LayoutShadowNode to be the window size. This is done through the
+ * UIManagerModule, and will then cause the children to layout as if they can fill the window.
*/
static class DialogRootViewGroup extends ReactViewGroup implements RootView {
private final JSTouchDispatcher mJSTouchDispatcher = new JSTouchDispatcher(this);
+ private final Point mMinPoint = new Point();
+ private final Point mMaxPoint = new Point();
public DialogRootViewGroup(Context context) {
super(context);
@@ -272,8 +282,33 @@ protected void onSizeChanged(final int w, final int h, int oldw, int oldh) {
new Runnable() {
@Override
public void run() {
+ // To get the size of the screen, we use information from the WindowManager and
+ // default Display. We don't use DisplayMetricsHolder, or Display#getSize() because
+ // they return values that include the status bar. We only want the values of what
+ // will actually be shown on screen.
+ Context context = getContext();
+ WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+ Display display = Assertions.assertNotNull(wm.getDefaultDisplay());
+ // getCurrentSizeRange will return the min and max width and height that the window
+ // can be
+ display.getCurrentSizeRange(mMinPoint, mMaxPoint);
+
+ int width, height;
+ int rotation = display.getRotation();
+ if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) {
+ // If we are vertical the width value comes from min width and height comes from
+ // max height
+ width = mMinPoint.x;
+ height = mMaxPoint.y;
+ } else {
+ // If we are horizontal the width value comes from max width and height comes from
+ // min height
+ width = mMaxPoint.x;
+ height = mMinPoint.y;
+ }
+
((ReactContext) getContext()).getNativeModule(UIManagerModule.class)
- .updateNodeSize(getChildAt(0).getId(), w, h);
+ .updateNodeSize(getChildAt(0).getId(), width, height);
}
});
}

0 comments on commit 4941cbc

Please sign in to comment.