[WIP] Handle status bar without is status bar translucent android option
Summary
During the discussion #5851 it was suggested that we could handle status bar without passing special flag. I attached observer that listens to StatusBar changes and keep track if the color is translucent and what is its height. Thanks to that I can change top insets automatically. The PR is WIP - if we decide to go with it I need to remove unused flag or deprecate it
| Before without useAnimatedKeyboard | Before with useAnimatedKeyboard | After |
|---|---|---|
Test plan
Turn of navigation headers if visible, and then you use this Example:
Example
import React, { useEffect, useState } from 'react';
import Animated, {
useAnimatedKeyboard,
useAnimatedReaction,
useAnimatedStyle,
} from 'react-native-reanimated';
import {
Platform,
StatusBar,
StyleSheet,
TextInput,
View,
Text,
Button,
} from 'react-native';
export default function EmptyExample() {
const [statusBarHidden, setStatusBarHidden] = useState(false);
const [statusBarTranslucent, setStatusBarTranslucent] = useState(false);
const keyboard = useAnimatedKeyboard();
const animatedStyles = useAnimatedStyle(() => ({
transform: [{ translateY: -keyboard.height.value }],
}));
useAnimatedReaction(
() => {
return keyboard.height.value;
},
(currentValue) => console.log(currentValue)
);
return (
<Animated.View
style={[
styles.container,
animatedStyles,
{ justifyContent: 'flex-end', borderWidth: 5, borderColor: '#ff0', backgroundColor: "#222" },
]}>
<StatusBar
barStyle="default"
hidden={statusBarHidden}
backgroundColor={statusBarTranslucent ? 'transparent' : undefined}
translucent={statusBarTranslucent}
/>
<Button
title="Toggle statusBackgroundColor"
onPress={() => setStatusBarTranslucent((hidden) => !hidden)}
/>
<Button
title="Toggle StatusBar"
onPress={() => setStatusBarHidden((hidden) => !hidden)}
/>
<Button
title="Show Warning"
onPress={() => console.warn('WARNING!!!!')}
/>
<View
style={[
styles.center,
{
height: 200,
backgroundColor: '#f0f',
borderWidth: 5,
borderColor: '#0ff',
},
]}>
<Text>{`Android ${Platform.constants['Release']}`}</Text>
<TextInput placeholder="Test" />
</View>
</Animated.View>
);
}
const styles = StyleSheet.create({
container: { flex: 1 },
center: { justifyContent: 'center', alignItems: 'center' },
});
This solution works, but we're investigating this in terms of performance, as in current state it may cause problems.
@maciekstosio recently I had to use react-native-keyboard-controller and react-native-avoid-softinput and they both had issues with useAnimatedKeyboard and edge to edge setup with react-native-unistyles. The status bar is flickering when useAnimatedKeyboard does it's magic causing weird layout effects.
Both input handlers set decorFitsSystemWindow dynamically but on react-native-unistyles @2.8.1 it's static -> false.
some more info on rn-avoid-softinput:
- https://github.com/mateusz1913/react-native-avoid-softinput/issues/200#issuecomment-2007527099
Just wanted to bring this to your attention.
cc: @jpudysz
Using ViewTreeObserver.OnDrawListener is not performant. It triggers the callback multiple times.
After months of debugging insets IMO there are two reliable ways to measure it:
-
WindowInsetsCompat- but requiresdecorFitsSystemWindowset to false - measuring root view and decor view and compare them - but we need to handle multiple edge cases
@maciekstosio if you want I can share some knowledge here
Using
ViewTreeObserver.OnDrawListeneris not performant. It triggers the callback multiple times. After months of debugging insets IMO there are two reliable ways to measure it:
WindowInsetsCompat- but requiresdecorFitsSystemWindowset to false- measuring root view and decor view and compare them - but we need to handle multiple edge cases
@maciekstosio if you want I can share some knowledge here
Yeah, that's why it's on hold for so long :D Although I'm not sure if those two solution are feasible - we have decorFitsSystemWindow(false) to observe keyboard height, but as far as I remember the problem with transparent status bar is that insets do not change, just the background and I couldn't find a way to observe that (other then on every draw). Anyway, I'm more than happy to discuss it with you, I'll write you.