5

I have a "fullscreen" background image that is used for a page:

container = {
    flex: 1,
    width: null,
    height: null
}

<View ...>
    ...
    <Image ... styles={container}>
        ...
        <TextInput ... />
        ...
    </Image>
</View>

However, as you may notice, tapping on the text input will open up the keyboard and the height of view changes. Since the image is set to cover, it also adjusts as the dimension of the view changes. I want the height of the parent view and the <Image> to not be affected by the keyboard, and only the content of the <Image> should be pushed up by the keyboard.

I'm aware there is a <KeyboardAvoidingView> available but I am not sure how to use it or does it even handle this situation.

Any ideas would be great. Thanks.

Derek 朕會功夫
  • 92,235
  • 44
  • 185
  • 247

6 Answers6

27

I do like this in React Native and it works :

backgroundImage: {
    position: 'absolute',
    left: 0,
    top: 0,
    width: Dimensions.get('window').width,
    height: Dimensions.get('window').height,
},
gprathour
  • 14,813
  • 5
  • 66
  • 90
Hossein Arsheia
  • 361
  • 1
  • 4
  • 7
13

I added

android:windowSoftInputMode="adjustPan"

to my AndroidManifest.xml and it worked out perfectly - the view doesn't get shrinked and the text inputs got pushed up.

Derek 朕會功夫
  • 92,235
  • 44
  • 185
  • 247
  • `android:windowSoftInputMode="adjustPan"` should be inside https://developer.android.com/guide/topics/manifest/activity-element#wsoft I already had the property there so I have only replaced the value. – Black Nov 26 '18 at 11:18
3

Here's the solution I found to the same problem that I've faced. As you said, you can use react-native-keyboard-avoiding-view which is a really good way of avoiding keyboard and this solution implements that.

So what we have here is an image with style imageStyle wrapping everything.

render() {
  return(
   <Image source={{uri: 'blabla'}} style={imageStyle}>
     <View style={styles.container}>
       <KeyboardAwareScrollView>
         <TouchableOpacity onPress={this.abc.bind(this)}>
           <View style={styles.abc}>
             <Text>Test</Text>
           </View>
         </TouchableOpacity>
         ...
       </KeyboardAwareScrollView>
       ...
     </View>
   </Image>
  )
} 

and imageStyle:

const imageStyle = {
  width: Dimensions.get('window').width,
  height: Dimensions.get('window').height,
  resizeMode: 'stretch',
}

Bonus: If you are going to support screen rotations, you can do:

const { width, height } = Dimensions.get('window')
const imageStyle = {
  width: width < height ? width : height,
  height: width < height ? height : width,
  resizeMode: 'stretch',
}
eden
  • 5,876
  • 2
  • 28
  • 43
3

Change

android:windowSoftInputMode="adjustResize"

To

android:windowSoftInputMode="adjustPan"

In android/app/src/main/AndroidManifest.xml, block activity

ImYuta
  • 41
  • 6
1

I wanted to accomplish the same thing, but without changing windowSoftInputMode.

I was able to do it by setting just the height of the image to Dimensions.get('window').height.

My background image stays put when the keyboard opens, but the components sitting on top of it move out of the way.

Rob
  • 123
  • 1
  • 10
0

Because I was using React Navigation also, I was having issues using the window height effectively. I have a notification stuck to the bottom, and it was off the screen. My eventual solution was to close the ImageBackground element prior to the children:

<View style={styles.container}>
  <ImageBackground
    source={BACKGROUND}
    imageStyle={{ resizeMode: 'repeat' }}
    style={styles.imageBackground}
  />
  <SafeAreaView style={{ flex: 1, justifyContent: 'space-between' }}>
    <KeyboardAvoidingView behavior={Platform.OS === 'ios' ? "padding" : "height"} style={{flex: 1, justifyContent: 'space-between'}}>
      {children}
    </KeyboardAvoidingView>
    <Notification/>
  </SafeAreaView>
</View>

With styles looking like

export const { width: screenWidth, height: screenHeight } = Dimensions.get('window');
export const styles = StyleSheet.create(
{
  notification: { position: 'absolute', bottom: 0, left: 0, right: 0, alignItems: 'stretch'},
  imageBackground: { position: 'absolute', left: 0, top: 0, height: screenHeight, width: screenWidth },
  container: {
    flex: 1,
    alignItems: 'stretch',
    justifyContent: 'space-around',
  },
});
Enoch
  • 202
  • 1
  • 10