Skip to content

Commit 39ef764

Browse files
committed
Fix layout issues with keyboard on android
1 parent 940bdf5 commit 39ef764

2 files changed

Lines changed: 214 additions & 0 deletions

File tree

Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
diff --git a/node_modules/react-native-screens/android/src/fabric/java/com/swmansion/rnscreens/FabricEnabledViewGroup.kt b/node_modules/react-native-screens/android/src/fabric/java/com/swmansion/rnscreens/FabricEnabledViewGroup.kt
2+
index 2d946c4..ccda8f3 100644
3+
--- a/node_modules/react-native-screens/android/src/fabric/java/com/swmansion/rnscreens/FabricEnabledViewGroup.kt
4+
+++ b/node_modules/react-native-screens/android/src/fabric/java/com/swmansion/rnscreens/FabricEnabledViewGroup.kt
5+
@@ -12,38 +12,36 @@ import kotlin.math.abs
6+
abstract class FabricEnabledViewGroup constructor(context: ReactContext?) : ViewGroup(context), FabricViewStateManager.HasFabricViewStateManager {
7+
private val mFabricViewStateManager: FabricViewStateManager = FabricViewStateManager()
8+
9+
- private var lastSetWidth = 0f
10+
- private var lastSetHeight = 0f
11+
+ private var lastHeaderHeight: Double = 0.0
12+
13+
override fun getFabricViewStateManager(): FabricViewStateManager {
14+
return mFabricViewStateManager
15+
}
16+
17+
- protected fun updateScreenSizeFabric(width: Int, height: Int) {
18+
- updateState(width, height)
19+
+ protected fun updateScreenSizeFabric(width: Int, height: Int, headerHeight: Double) {
20+
+ updateState(width, height, headerHeight)
21+
}
22+
23+
@UiThread
24+
- fun updateState(width: Int, height: Int) {
25+
+ fun updateState(width: Int, height: Int, headerHeight: Double) {
26+
val realWidth: Float = PixelUtil.toDIPFromPixel(width.toFloat())
27+
val realHeight: Float = PixelUtil.toDIPFromPixel(height.toFloat())
28+
29+
// Check incoming state values. If they're already the correct value, return early to prevent
30+
// infinite UpdateState/SetState loop.
31+
- val delta = 0.9f
32+
- if (abs(lastSetWidth - realWidth) < delta &&
33+
- abs(lastSetHeight - realHeight) < delta
34+
- ) {
35+
+ val delta = 0.9
36+
+ if (abs(lastHeaderHeight - headerHeight) < delta) {
37+
return
38+
}
39+
40+
- lastSetWidth = realWidth
41+
- lastSetHeight = realHeight
42+
+ lastHeaderHeight = headerHeight
43+
44+
mFabricViewStateManager.setState {
45+
val map: WritableMap = WritableNativeMap()
46+
map.putDouble("frameWidth", realWidth.toDouble())
47+
map.putDouble("frameHeight", realHeight.toDouble())
48+
+ map.putDouble("contentOffsetX", 0.0)
49+
+ map.putDouble("contentOffsetY", headerHeight)
50+
map
51+
}
52+
}
53+
diff --git a/node_modules/react-native-screens/android/src/main/java/com/swmansion/rnscreens/Screen.kt b/node_modules/react-native-screens/android/src/main/java/com/swmansion/rnscreens/Screen.kt
54+
index a7d28f9..b9087b2 100644
55+
--- a/node_modules/react-native-screens/android/src/main/java/com/swmansion/rnscreens/Screen.kt
56+
+++ b/node_modules/react-native-screens/android/src/main/java/com/swmansion/rnscreens/Screen.kt
57+
@@ -72,9 +72,9 @@ class Screen constructor(context: ReactContext?) : FabricEnabledViewGroup(contex
58+
val width = r - l
59+
val height = b - t
60+
61+
- calculateHeaderHeight()
62+
+ val headerHeight = calculateHeaderHeight()
63+
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
64+
- updateScreenSizeFabric(width, height)
65+
+ updateScreenSizeFabric(width, height, headerHeight.first)
66+
} else {
67+
updateScreenSizePaper(width, height)
68+
}
69+
@@ -246,7 +246,7 @@ class Screen constructor(context: ReactContext?) : FabricEnabledViewGroup(contex
70+
mNativeBackButtonDismissalEnabled = enableNativeBackButtonDismissal
71+
}
72+
73+
- private fun calculateHeaderHeight() {
74+
+ private fun calculateHeaderHeight(): Pair<Double, Double> {
75+
val actionBarTv = TypedValue()
76+
val resolvedActionBarSize = context.theme.resolveAttribute(android.R.attr.actionBarSize, actionBarTv, true)
77+
78+
@@ -265,6 +265,8 @@ class Screen constructor(context: ReactContext?) : FabricEnabledViewGroup(contex
79+
val totalHeight = actionBarHeight + statusBarHeight
80+
UIManagerHelper.getEventDispatcherForReactTag(context as ReactContext, id)
81+
?.dispatchEvent(HeaderHeightChangeEvent(id, totalHeight))
82+
+
83+
+ return actionBarHeight to statusBarHeight
84+
}
85+
86+
enum class StackPresentation {
87+
diff --git a/node_modules/react-native-screens/common/cpp/react/renderer/components/rnscreens/RNSScreenComponentDescriptor.h b/node_modules/react-native-screens/common/cpp/react/renderer/components/rnscreens/RNSScreenComponentDescriptor.h
88+
index 67194d3..c1a1b40 100644
89+
--- a/node_modules/react-native-screens/common/cpp/react/renderer/components/rnscreens/RNSScreenComponentDescriptor.h
90+
+++ b/node_modules/react-native-screens/common/cpp/react/renderer/components/rnscreens/RNSScreenComponentDescriptor.h
91+
@@ -13,7 +13,7 @@ class RNSScreenComponentDescriptor final
92+
using ConcreteComponentDescriptor::ConcreteComponentDescriptor;
93+
94+
void adopt(ShadowNode& shadowNode) const override {
95+
- react_native_assert(
96+
+ react_native_assert(
97+
dynamic_cast<RNSScreenShadowNode*>(&shadowNode));
98+
auto& screenShadowNode =
99+
static_cast<RNSScreenShadowNode&>(shadowNode);
100+
@@ -28,10 +28,7 @@ class RNSScreenComponentDescriptor final
101+
shadowNode.getState());
102+
auto stateData = state->getData();
103+
104+
- if (stateData.frameSize.width != 0 && stateData.frameSize.height != 0) {
105+
- layoutableShadowNode.setSize(
106+
- Size{stateData.frameSize.width, stateData.frameSize.height});
107+
- }
108+
+ layoutableShadowNode.setPadding({.bottom = stateData.contentOffset.y});
109+
110+
ConcreteComponentDescriptor::adopt(shadowNode);
111+
}
112+
diff --git a/node_modules/react-native-screens/common/cpp/react/renderer/components/rnscreens/RNSScreenShadowNode.cpp b/node_modules/react-native-screens/common/cpp/react/renderer/components/rnscreens/RNSScreenShadowNode.cpp
113+
index ba61ed8..0e3746e 100644
114+
--- a/node_modules/react-native-screens/common/cpp/react/renderer/components/rnscreens/RNSScreenShadowNode.cpp
115+
+++ b/node_modules/react-native-screens/common/cpp/react/renderer/components/rnscreens/RNSScreenShadowNode.cpp
116+
@@ -5,5 +5,11 @@ namespace react {
117+
118+
extern const char RNSScreenComponentName[] = "RNSScreen";
119+
120+
+Point RNSScreenShadowNode::getContentOriginOffset() const {
121+
+ auto stateData = getStateData();
122+
+ auto contentOffset = stateData.contentOffset;
123+
+ return {contentOffset.x, contentOffset.y};
124+
+}
125+
+
126+
} // namespace react
127+
} // namespace facebook
128+
diff --git a/node_modules/react-native-screens/common/cpp/react/renderer/components/rnscreens/RNSScreenShadowNode.h b/node_modules/react-native-screens/common/cpp/react/renderer/components/rnscreens/RNSScreenShadowNode.h
129+
index ef25dd1..bbd7599 100644
130+
--- a/node_modules/react-native-screens/common/cpp/react/renderer/components/rnscreens/RNSScreenShadowNode.h
131+
+++ b/node_modules/react-native-screens/common/cpp/react/renderer/components/rnscreens/RNSScreenShadowNode.h
132+
@@ -19,9 +19,11 @@ class JSI_EXPORT RNSScreenShadowNode final : public ConcreteViewShadowNode<
133+
public:
134+
using ConcreteViewShadowNode::ConcreteViewShadowNode;
135+
136+
+ Point getContentOriginOffset() const override;
137+
+
138+
static ShadowNodeTraits BaseTraits() {
139+
auto traits = ConcreteViewShadowNode::BaseTraits();
140+
- traits.set(ShadowNodeTraits::Trait::RootNodeKind);
141+
+ // traits.set(ShadowNodeTraits::Trait::RootNodeKind);
142+
return traits;
143+
}
144+
};
145+
diff --git a/node_modules/react-native-screens/common/cpp/react/renderer/components/rnscreens/RNSScreenState.cpp b/node_modules/react-native-screens/common/cpp/react/renderer/components/rnscreens/RNSScreenState.cpp
146+
index 69c77a6..6c3b8ca 100644
147+
--- a/node_modules/react-native-screens/common/cpp/react/renderer/components/rnscreens/RNSScreenState.cpp
148+
+++ b/node_modules/react-native-screens/common/cpp/react/renderer/components/rnscreens/RNSScreenState.cpp
149+
@@ -6,8 +6,8 @@ namespace react {
150+
#ifdef ANDROID
151+
folly::dynamic RNSScreenState::getDynamic() const {
152+
return folly::dynamic::object("frameWidth", frameSize.width)(
153+
- "frameHeight", frameSize.height);
154+
-}
155+
+ "frameHeight", frameSize.height)("contentOffsetX", contentOffset.x)("contentOffsetY", contentOffset.y);
156+
+ }
157+
#endif
158+
159+
} // namespace react
160+
diff --git a/node_modules/react-native-screens/common/cpp/react/renderer/components/rnscreens/RNSScreenState.h b/node_modules/react-native-screens/common/cpp/react/renderer/components/rnscreens/RNSScreenState.h
161+
index ce09807..e26d411 100644
162+
--- a/node_modules/react-native-screens/common/cpp/react/renderer/components/rnscreens/RNSScreenState.h
163+
+++ b/node_modules/react-native-screens/common/cpp/react/renderer/components/rnscreens/RNSScreenState.h
164+
@@ -17,7 +17,7 @@ class JSI_EXPORT RNSScreenState final {
165+
using Shared = std::shared_ptr<const RNSScreenState>;
166+
167+
RNSScreenState(){};
168+
- RNSScreenState(Size frameSize_) : frameSize(frameSize_){};
169+
+ RNSScreenState(Size frameSize_, Point contentOffset_) : frameSize(frameSize_), contentOffset(contentOffset_){};
170+
171+
#ifdef ANDROID
172+
RNSScreenState(
173+
@@ -25,10 +25,14 @@ class JSI_EXPORT RNSScreenState final {
174+
folly::dynamic data)
175+
: frameSize(Size{
176+
(Float)data["frameWidth"].getDouble(),
177+
- (Float)data["frameHeight"].getDouble()}){};
178+
+ (Float)data["frameHeight"].getDouble()}),
179+
+ contentOffset(Point{
180+
+ (Float)data["contentOffsetX"].getDouble(),
181+
+ (Float)data["contentOffsetY"].getDouble()}){};
182+
#endif
183+
184+
const Size frameSize{};
185+
+ Point contentOffset;
186+
187+
#ifdef ANDROID
188+
folly::dynamic getDynamic() const;
189+
diff --git a/node_modules/react-native-screens/ios/RNSScreen.h b/node_modules/react-native-screens/ios/RNSScreen.h
190+
index f1bd9d8..797fc12 100644
191+
--- a/node_modules/react-native-screens/ios/RNSScreen.h
192+
+++ b/node_modules/react-native-screens/ios/RNSScreen.h
193+
@@ -42,6 +42,7 @@ namespace react = facebook::react;
194+
#ifdef RCT_NEW_ARCH_ENABLED
195+
- (void)setViewToSnapshot:(UIView *)snapshot;
196+
- (void)resetViewToScreen;
197+
+- (CGFloat)calculateHeaderHeightIsModal:(BOOL)isModal;
198+
#endif
199+
200+
@end
201+
diff --git a/node_modules/react-native-screens/ios/RNSScreen.mm b/node_modules/react-native-screens/ios/RNSScreen.mm
202+
index 4b24cff..8f480ca 100644
203+
--- a/node_modules/react-native-screens/ios/RNSScreen.mm
204+
+++ b/node_modules/react-native-screens/ios/RNSScreen.mm
205+
@@ -107,7 +107,8 @@ - (void)updateBounds
206+
{
207+
#ifdef RCT_NEW_ARCH_ENABLED
208+
if (_state != nullptr) {
209+
- auto newState = react::RNSScreenState{RCTSizeFromCGSize(self.bounds.size)};
210+
+ CGFloat headerHeight = [_controller calculateHeaderHeightIsModal:self.isPresentedAsNativeModal];
211+
+ auto newState = react::RNSScreenState{RCTSizeFromCGSize(self.bounds.size), RCTPointFromCGPoint(CGPointMake(0, headerHeight))};
212+
_state->updateState(std::move(newState));
213+
UINavigationController *navctr = _controller.navigationController;
214+
[navctr.view setNeedsLayout];
File renamed without changes.

0 commit comments

Comments
 (0)