Skip to content

feat: add support for isNavigationBarTranslucentAndroid#6431

Merged
maciekstosio merged 5 commits intomainfrom
@maciekstosio/Add-support-for-isNavigationBarTranslucentAndroid
Sep 18, 2024
Merged

feat: add support for isNavigationBarTranslucentAndroid#6431
maciekstosio merged 5 commits intomainfrom
@maciekstosio/Add-support-for-isNavigationBarTranslucentAndroid

Conversation

@maciekstosio
Copy link
Contributor

@maciekstosio maciekstosio commented Aug 20, 2024

Summary

Resolves #6043. For StatusBar we have a flag that removes top padding when we want to render RN stuff "under" StatusBar. A similar problem was raised in #6043, but for NavigationBar, so I added another flag isNavigationBarTranslucentAndroid that removes bottom padding as well. Currently, I see no way to make it automatic. I tried one approach to remove the flags in #5889, but it doesn't seem to be the performant solution.

Preview

Before After without flag After with flag
before after-without-flag after-with-flag

Test plan

Testing is a bit tricky, because an example from the issue uses a navigation bar package from Expo, which requires Expo and our example app doesn't have Expo.

What I did:

Steps
# clone reanimated from current branch 
git clone https://github.com/software-mansion/react-native-reanimated.git
# checkout current branch
git checkout @maciekstosio/Add-support-for-isNavigationBarTranslucentAndroid
# install
yarn && yarn build
# build npm package
cd packages/react-native-reanimated
./createNPMPackage.sh --fresh
# next, create simple expo project
npx create-expo-stack
# install library for navigation bar
npx expo install expo-navigation-bar
# install reanimated 
npx expo install react-native-reanimated
# replace in package.json path to locally-build package i.e.:
"react-native-reanimated": "file:react-native-reanimated.tgz"
# yarn install 
# npx expo run:android
App.tsx to test
import * as NavigationBar from 'expo-navigation-bar';
import React, { useEffect } from 'react';
import Animated, {
  useAnimatedKeyboard,
  useAnimatedStyle,
} from 'react-native-reanimated';
import {
  Platform,
  StatusBar,
  StyleSheet,
  TextInput,
  View,
  Text,
  Button,
} from 'react-native';

export default function EmptyExample() {
  const keyboard = useAnimatedKeyboard({
    isNavigationBarTranslucentAndroid: true,
  });

  const animatedStyles = useAnimatedStyle(() => ({
    transform: [{ translateY: -keyboard.height.value }],
  }));

  useEffect(() => {
    StatusBar.setBarStyle('dark-content');
    NavigationBar.setBackgroundColorAsync('transparent');
  }, []);

  return (
    <Animated.View
      style={[
        styles.container,
        animatedStyles,
        { justifyContent: 'flex-end', borderWidth: 5, borderColor: '#ff0' },
      ]}>
      <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, backgroundColor: 'rgba(255,0,255,0.2)' },
  center: { justifyContent: 'center', alignItems: 'center' },
});

@maciekstosio maciekstosio requested a review from piaskowyk August 23, 2024 13:58
@maciekstosio maciekstosio marked this pull request as ready for review August 23, 2024 13:58
@janicduplessis
Copy link
Contributor

janicduplessis commented Aug 27, 2024

I have a patch in my app to do this (but without the config parameter part). I think you might also need to adjust the value here for when using the keyboard height.

diff --git a/android/src/main/java/com/swmansion/reanimated/keyboard/Keyboard.java b/android/src/main/java/com/swmansion/reanimated/keyboard/Keyboard.java
index 7aa497e2bc39a374818a825728f61f0a6ebec534..3d1ed85b8dbbf0e091c1f38ef0644efb632acf54 100644
--- a/android/src/main/java/com/swmansion/reanimated/keyboard/Keyboard.java
+++ b/android/src/main/java/com/swmansion/reanimated/keyboard/Keyboard.java
@@ -20,7 +20,7 @@ public class Keyboard {
 
   public void updateHeight(WindowInsetsCompat insets) {
     int contentBottomInset = insets.getInsets(CONTENT_TYPE_MASK).bottom;
-    int systemBarBottomInset = insets.getInsets(SYSTEM_BAR_TYPE_MASK).bottom;
+    int systemBarBottomInset = 0; // <- This should be based on isNavigationBarTranslucentAndroid
     int keyboardHeightDip = contentBottomInset - systemBarBottomInset;
     int keyboardHeight = (int) PixelUtil.toDIPFromPixel(Math.max(0, keyboardHeightDip));
     if (keyboardHeight <= 0 && mState == KeyboardState.OPEN) {

@maciekstosio
Copy link
Contributor Author

maciekstosio commented Aug 29, 2024

@janicduplessis Nice catch, thanks! Fixed in 80531ea.

@raycar5
Copy link

raycar5 commented Sep 11, 2024

Waiting on this for my project, might use this branch for now, good job!

Copy link
Member

@piaskowyk piaskowyk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good 👍

@maciekstosio maciekstosio added this pull request to the merge queue Sep 18, 2024
Merged via the queue into main with commit 5a90376 Sep 18, 2024
@maciekstosio maciekstosio deleted the @maciekstosio/Add-support-for-isNavigationBarTranslucentAndroid branch September 18, 2024 09:41
r0h0gg6 pushed a commit to r0h0gg6/react-native-reanimated that referenced this pull request Jul 28, 2025
…sion#6431)

## Summary

Resolves software-mansion#6043. For StatusBar we have a flag that removes top padding
when we want to render RN stuff "under" StatusBar. A similar problem was
raised in software-mansion#6043, but for NavigationBar, so I added another flag
`isNavigationBarTranslucentAndroid` that removes bottom padding as well.
Currently, I see no way to make it automatic. I tried one approach to
remove the flags in software-mansion#5889, but it doesn't seem to be the performant
solution.

## Preview 

|Before|After without flag|After with flag|
|-|-|-|
|<img width="602" alt="before"
src="https://github.com/user-attachments/assets/0032efbe-342a-4e06-81ee-f7351bb032f7">|<img
width="602" alt="after-without-flag"
src="https://github.com/user-attachments/assets/6f259329-9bf4-4bbb-8ce4-32d671e65a5a">|<img
width="602" alt="after-with-flag"
src="https://github.com/user-attachments/assets/81c43052-f3b3-4a3b-a9cb-bd974e851c43">|

## Test plan

Testing is a bit tricky, because an example from the issue uses a
navigation bar package from Expo, which requires Expo and our example
app doesn't have Expo.

What I did:

<details>
<summary>Steps</summary>

```bash
# clone reanimated from current branch 
git clone https://github.com/software-mansion/react-native-reanimated.git
# checkout current branch
git checkout @maciekstosio/Add-support-for-isNavigationBarTranslucentAndroid
# install
yarn && yarn build
# build npm package
cd packages/react-native-reanimated
./createNPMPackage.sh --fresh
# next, create simple expo project
npx create-expo-stack
# install library for navigation bar
npx expo install expo-navigation-bar
# install reanimated 
npx expo install react-native-reanimated
# replace in package.json path to locally-build package i.e.:
"react-native-reanimated": "file:react-native-reanimated.tgz"
# yarn install 
# npx expo run:android
```

</details>

<details>
<summary>App.tsx to test</summary>

```jsx
import * as NavigationBar from 'expo-navigation-bar';
import React, { useEffect } from 'react';
import Animated, {
  useAnimatedKeyboard,
  useAnimatedStyle,
} from 'react-native-reanimated';
import {
  Platform,
  StatusBar,
  StyleSheet,
  TextInput,
  View,
  Text,
  Button,
} from 'react-native';

export default function EmptyExample() {
  const keyboard = useAnimatedKeyboard({
    isNavigationBarTranslucentAndroid: true,
  });

  const animatedStyles = useAnimatedStyle(() => ({
    transform: [{ translateY: -keyboard.height.value }],
  }));

  useEffect(() => {
    StatusBar.setBarStyle('dark-content');
    NavigationBar.setBackgroundColorAsync('transparent');
  }, []);

  return (
    <Animated.View
      style={[
        styles.container,
        animatedStyles,
        { justifyContent: 'flex-end', borderWidth: 5, borderColor: '#ff0' },
      ]}>
      <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, backgroundColor: 'rgba(255,0,255,0.2)' },
  center: { justifyContent: 'center', alignItems: 'center' },
});
```

</details>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

useAnimatedKeyboard break navigation color

4 participants