Support orientation change on modals
Summary: This automatically changes the size of the modal by listening to dialog size changes and propagating those changes through UIManager. In detail: I've looked into three ways of doing this: 1. Send `onSizeChanged` events/info from the View to the CSSNode directly. This is kinda hacky because you would need to hold a reference to the CSSNode somewhere, either in the View or in the ViewManager. But then you'll have to take care of the lifecycle of the CSSNode, so that you don't update it after it has been dismissed. Not great. 2. The version we went for, is to just update the size of the corresponding CSSNode in the same way we do it for root nodes: we inform the UIManager that the size of the root node has changed, and it will propagate that change, triggering a `dispatchViewUpdates` if none is underway, so that the layout is updated. 3. The other solution we thought of is to treat the Modal as a root view. This would mean rendering an application with the tag of the Modal as the root of the application. That tag would be received by calling some method into UIManager and ReactModalHostManager to create a new RootView, create a Dialog and plop the root view in it. The idea was to maintain the JS API that we now have, but make the implementation more correct (ie. since both RootView and the Modal must deal with touch handling), and could have other benefits (ie. no hacks necessary for making the inspector work on top of modals). However, the change is not trivial and I don't know just how much code would have to be changed to make this work correctly. We might revisit this at a later stage, after we've done more work on having several root views at the same time in the app. Reviewed By: foghina Differential Revision: D3841379 fbshipit-source-id: f5e363e27041b785cf44eb59da04bc789306ddb9
This commit is contained in:
parent
178407da40
commit
82c8c97898
|
@ -130,16 +130,17 @@ public class UIImplementation {
|
|||
}
|
||||
|
||||
/**
|
||||
* Invoked when native view that corresponds to a root node has its size changed.
|
||||
* Invoked when native view that corresponds to a root node, or acts as a root view (ie. Modals)
|
||||
* has its size changed.
|
||||
*/
|
||||
public void updateRootNodeSize(
|
||||
int rootViewTag,
|
||||
public void updateNodeSize(
|
||||
int nodeViewTag,
|
||||
int newWidth,
|
||||
int newHeight,
|
||||
EventDispatcher eventDispatcher) {
|
||||
ReactShadowNode rootCSSNode = mShadowNodeRegistry.getNode(rootViewTag);
|
||||
rootCSSNode.setStyleWidth(newWidth);
|
||||
rootCSSNode.setStyleHeight(newHeight);
|
||||
ReactShadowNode cssNode = mShadowNodeRegistry.getNode(nodeViewTag);
|
||||
cssNode.setStyleWidth(newWidth);
|
||||
cssNode.setStyleHeight(newHeight);
|
||||
|
||||
// If we're in the middle of a batch, the change will automatically be dispatched at the end of
|
||||
// the batch. As all batches are executed as a single runnable on the event queue this should
|
||||
|
|
|
@ -192,7 +192,7 @@ public class UIManagerModule extends ReactContextBaseJavaModule implements
|
|||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateRootNodeSize(tag, width, height);
|
||||
updateNodeSize(tag, width, height);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -206,10 +206,10 @@ public class UIManagerModule extends ReactContextBaseJavaModule implements
|
|||
mUIImplementation.removeRootView(rootViewTag);
|
||||
}
|
||||
|
||||
private void updateRootNodeSize(int rootViewTag, int newWidth, int newHeight) {
|
||||
public void updateNodeSize(int nodeViewTag, int newWidth, int newHeight) {
|
||||
getReactApplicationContext().assertOnNativeModulesQueueThread();
|
||||
|
||||
mUIImplementation.updateRootNodeSize(rootViewTag, newWidth, newHeight, mEventDispatcher);
|
||||
mUIImplementation.updateNodeSize(nodeViewTag, newWidth, newHeight, mEventDispatcher);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
|
|
|
@ -264,6 +264,21 @@ public class ReactModalHostView extends ViewGroup implements LifecycleEventListe
|
|||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSizeChanged(final int w, final int h, int oldw, int oldh) {
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
if (getChildCount() > 0) {
|
||||
((ReactContext) getContext()).runOnNativeModulesQueueThread(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
((ReactContext) getContext()).getNativeModule(UIManagerModule.class)
|
||||
.updateNodeSize(getChildAt(0).getId(), w, h);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent event) {
|
||||
mJSTouchDispatcher.handleTouchEvent(event, getEventDispatcher());
|
||||
|
|
Loading…
Reference in New Issue