Evanss
Evanss

Reputation: 23563

Hide component under a ScrollView when keyboard is open on Android in React Native?

My layout is a ScrollView above a footer. When the keyboard isnt open I need the footer to always be visible on the screen:

https://snack.expo.io/@jamesweblondon/privileged-cashew1

export default function App() {
  return (
    <SafeAreaView style={styles.container}>
      <ScrollView style={styles.content}>
        <TextInput style={styles.input} value={"Text Input"} />
      </ScrollView>

      <View style={styles.footer}>
        <Text>Footer</Text>
      </View>
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  content: {
    backgroundColor: "tomato",
    padding: 50,
  },
  input: {
    backgroundColor: "grey",
    padding: 50,
  },
  footer: {
    backgroundColor: "green",
    padding: 50,
  },
});

This works great on iOS. When the keyboard opens you no longer see the footer: enter image description here

However on Android the footer moves above the keyboard:

enter image description here

Can I stop this behaviour? Ive tried using Keyboard events however keyboardWillShow and keyboardWillHide arn't supported on Android. If I use keyboardDidShow and keyboardDidHide then the delay means the footer is visible as the keyboard animates up and then disappears, which feels jerky and unpleasant.

export default function App() {
  const [keyboardIsOpen, setKeyboardIsOpen] = React.useState(false);
  Keyboard.addListener("keyboardDidShow", () => {
    setKeyboardIsOpen(true);
  });
  Keyboard.addListener("keyboardDidHide", () => {
    setKeyboardIsOpen(false);
  });
  return (
    <SafeAreaView style={styles.container}>
      <ScrollView style={styles.content}>
        <TextInput style={styles.input} value={"Text Input"} />
      </ScrollView>

      {!keyboardIsOpen && (
        <View style={styles.footer}>
          <Text>Footer</Text>
        </View>
      )}
    </SafeAreaView>
  );
}

I also couldn't get it working with the KeyboardAvoidingView. I'm using Expo.

Upvotes: 6

Views: 7749

Answers (4)

Hemal
Hemal

Reputation: 3760

I found this ready npm package. You can install and use it.

Installation from https://www.npmjs.com/package/react-native-hide-with-keyboard

You just need to cover the component you want to hide, with <HideWithKeyboard>, for example,

<HideWithKeyboard>
    <Footer>
    <FooterTab>
    ...More Content Here...
    </FooterTab>
    </Footer>
</HideWithKeyboard>

Upvotes: 4

M Mahmud Hasan
M Mahmud Hasan

Reputation: 1173

It works for me of React-Native version: 0.61.2

android:windowSoftInputMode="adjustPan"

Upvotes: 0

Muhammad Numan
Muhammad Numan

Reputation: 25353

android:windowSoftInputMode already available in EXPO

here is demo: https://snack.expo.io/@nomi9995/01d462

you should give full height to container instead of flex:1

Code:

import React from "react";
import {
  StyleSheet,
  Text,
  View,
  ScrollView,
  SafeAreaView,
  TextInput,
  Dimensions
} from "react-native";

const height = Dimensions.get("window").height;
export default function App() {
  return (
    <SafeAreaView style={styles.container}>
      <ScrollView style={styles.content}>
      <View style={{flex:1}}>
        <TextInput style={styles.input} value={"Text Input"} />
        </View>
      </ScrollView>

      <View style={styles.footer}>
        <Text>Footer</Text>
      </View>
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: {
    height: height
  },
  content: {
    backgroundColor: "tomato",
    padding: 50,
  },
  input: {
    backgroundColor: "grey",
    padding: 50,
  },
  footer: {
    backgroundColor: "green",
    padding: 50
  },
});

enter image description here

Upvotes: 6

Imjaad
Imjaad

Reputation: 604

To handle this at the code level you can set the footer display property to absolute and bottom:0.

If you want to keep the footer at the bottom specially for the android you can set windowSoftInputMode in the manifest file. Inside the <application> and under <activity> block add the following property.

android:windowSoftInputMode="adjustResize"

then rebuild the app for android, if that still does not work you can also set that to

android:windowSoftInputMode="adjustPan"

Upvotes: 3

Related Questions