You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Summary:
Fixesfacebook#45857
The general idea behind this PR is the same for both platforms: dirty all nodes with `MeasurableYogaNode` trait when the layout is constrained with a new `fontSizeMultiplier`. There were a few caveats:
- `ParagraphShadowNode` marks its layout as clean in the constructor in most cases. To prevent that from using a stale measurement, I've added a `fontSizeMultiplier_` field in the node that keeps track of the font scale it was last laid out with. That value is then compared with the scale used to create the attributed string kept in the node's state. If those differ, the layout is not cleared.
- On Android, font scale wasn't passed down to the `SurfaceHandler`
- On Android, text measurement relies on cached `DisplayMetrics` which were not updated when the system font scale changed.
- `AndroidTextInputShadowNode` wasn't using `fontSizeMultiplier` at all. I needed to add it in all places where an `AttributedString` is constructed.
- When the `fontSizeMultiplier` is changed, the entire `ShadowTree` is cloned. I'm not sure if there's a reliable way of determining whether the node is mutable or not.
- Changing font scale and navigating back to the app on Android has the potential to cause a `SIGSEGV` but it also happens without changes in this PR.
## Changelog:
[GENERAL] [FIXED] - Fixed text not updating correctly after changing font scale in settings
Pull Request resolved: facebook#45978
Test Plan:
So far tested on the following code:
```jsx
function App() {
const [counter,setCounter] = useState(0);
const [text,setText] = useState('TextInput');
const [flag,setFlag] = useState(true);
return (
<SafeAreaView
style={{
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
}}
>
<Text style={{fontSize: 24}}>RN 24 Label Testing {flag ? 'A' : 'B'}</Text>
<TextInput value={text} onChangeText={setText} style={{fontSize: 24, borderWidth: 1}} placeholder="Placeholder" />
<Pressable onPress={() => setCounter(prevState => prevState + 1)} style={{backgroundColor: counter % 2 === 0 ? 'red' : 'blue', width: 200, height: 50}} />
<Pressable onPress={() => setFlag(!flag)} style={{backgroundColor: 'green', width: 200, height: 50}} />
</SafeAreaView>
);
}
```
Differential Revision: D71727907
Pulled By: j-piasecki
Copy file name to clipboardExpand all lines: packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputShadowNode.cpp
Copy file name to clipboardExpand all lines: packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputShadowNode.h
+7-4
Original file line number
Diff line number
Diff line change
@@ -70,19 +70,22 @@ class AndroidTextInputShadowNode final
70
70
* Creates a `State` object (with `AttributedText` and
0 commit comments