66#include < react/debug/react_native_assert.h>
77#include < react/renderer/components/rnscreens/Props.h>
88#include < react/renderer/components/rnscreens/utils/RectUtil.h>
9+ #include < react/renderer/components/root/RootShadowNode.h>
910#include < react/renderer/core/ConcreteComponentDescriptor.h>
11+ #include < react/renderer/uimanager/UIManager.h>
12+ #include < react/renderer/uimanager/UIManagerCommitHook.h>
13+ #include < memory>
1014#include " RNSScreenShadowNode.h"
15+ #include " RNSScreenShadowNodeCommitHook.h"
1116
1217namespace facebook {
1318namespace react {
@@ -16,9 +21,29 @@ using namespace rnscreens;
1621
1722class RNSScreenComponentDescriptor final
1823 : public ConcreteComponentDescriptor<RNSScreenShadowNode> {
24+ private:
25+ #ifdef ANDROID
26+ /*
27+ * A commit hook that triggers on `shadowTreeWillCommit` event,
28+ * and can read the properties of RootShadowNodes for determining screen
29+ * orientation.
30+ */
31+ mutable std::shared_ptr<RNSScreenShadowNodeCommitHook> commitHook_;
32+ /*
33+ * The following flag is expected to be set by RNSScreenShadowNodeCommitHook,
34+ * when it detects that screen orientation has changed
35+ * by comparing width to height of old and new ShadowNode revision.
36+ */
37+ mutable bool orientationDidChange_ = false ;
38+ #endif // Android specific
39+
1940 public:
2041 using ConcreteComponentDescriptor::ConcreteComponentDescriptor;
2142
43+ void setOrientationDidChange () {
44+ orientationDidChange_ = true ;
45+ }
46+
2247 void adopt (ShadowNode &shadowNode) const override {
2348 react_native_assert (dynamic_cast <RNSScreenShadowNode *>(&shadowNode));
2449 auto &screenShadowNode = static_cast <RNSScreenShadowNode &>(shadowNode);
@@ -34,7 +59,22 @@ class RNSScreenComponentDescriptor final
3459 auto stateData = state->getData ();
3560
3661#ifdef ANDROID
37- if (stateData.frameSize .width != 0 && stateData.frameSize .height != 0 ) {
62+ if (!commitHook_) {
63+ // The hook couldn't be attached in constructor because UIManager was
64+ // missing from ContextContainer. Instead, we do it here, on the first
65+ // call to the function. We don't anticipate any orientation changes that
66+ // we need to respond to prior to this.
67+ commitHook_ = std::make_shared<RNSScreenShadowNodeCommitHook>(
68+ contextContainer_, const_cast <RNSScreenComponentDescriptor *>(this ));
69+ }
70+
71+ if (orientationDidChange_) {
72+ orientationDidChange_ = false ;
73+ screenShadowNode.getStateDataMutable ().frameSize = {0 , 0 };
74+ screenShadowNode.getStateDataMutable ().contentOffset = {0 , 0 };
75+ layoutableShadowNode.setSize ({YGUndefined, YGUndefined});
76+ } else if (
77+ stateData.frameSize .width != 0 && stateData.frameSize .height != 0 ) {
3878 // When we receive dimensions from JVM side we can remove padding used for
3979 // correction, and we can stop applying height and offset corrections for
4080 // the frame.
0 commit comments