React-native: Android: KeyboardAvoidingView white-space on bottom of screen when android:windowTranslucentStatus is set to true

Created on 16 Dec 2019  路  19Comments  路  Source: facebook/react-native

KeyboardAvoidingView leaves space on bottom of screen when the keyboard is closed.
This bug manifests when the android:windowTranslucentStatus is set to true. (Note that this is the case for project initialized with Expo)

kav-bug

React Native version:

System:
    OS: macOS 10.15.2
    CPU: (4) x64 Intel(R) Core(TM) i5-4308U CPU @ 2.80GHz
    Memory: 68.76 MB / 8.00 GB
    Shell: 5.7.1 - /bin/zsh
  Binaries:
    Node: 12.4.0 - ~/.nvm/versions/node/v12.4.0/bin/node
    Yarn: 1.19.1 - ~/.nvm/versions/node/v12.4.0/bin/yarn
    npm: 6.13.1 - ~/.nvm/versions/node/v12.4.0/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  SDKs:
    iOS SDK:
      Platforms: iOS 13.2, DriverKit 19.0, macOS 10.15, tvOS 13.2, watchOS 6.1
    Android SDK:
      API Levels: 23, 26, 27, 28, 29
      Build Tools: 27.0.3, 28.0.3, 29.0.0
      System Images: android-28 | Intel x86 Atom_64, android-28 | Google APIs Intel x86 Atom, android-29 | Google APIs Intel x86 Atom
  IDEs:
    Android Studio: 3.5 AI-191.8026.42.35.5791312
    Xcode: 11.2.1/11B500 - /usr/bin/xcodebuild
  npmPackages:
    react: 16.9.0 => 16.9.0 
    react-native: 0.61.5 => 0.61.5 
  npmGlobalPackages:
    react-native-cli: 2.0.1

Steps To Reproduce

  1. Initialize a new RN project
  2. Add <item name="android:windowTranslucentStatus">true</item> to android/app/src/main/res/values/styles.xml
  3. Copy/paste the following code to App.js
import React from 'react';
import {TextInput, View, KeyboardAvoidingView} from 'react-native';

export default () => (
  <KeyboardAvoidingView behavior="padding" style={{flex: 1}}>
    <View
      style={{flex: 1, justifyContent: 'center', backgroundColor: 'yellow'}}>
      <TextInput placeholder="Tap here to open keyboard" />
    </View>
  </KeyboardAvoidingView>
);
  1. Run the app using react-native run-android
  2. Open and close the keyboard
  3. Observe the white-space on the bottom of the screen

Describe what you expected to happen:
It's expected for the yellow View to take up the whole space.

Snack, code example, screenshot, or link to a repository:
https://snack.expo.io/@hrastnik/keyboardavoidingview-bug

Keyboard Bug KeyboardAvoidingView Android

Most helpful comment

@Drzaln @dhruv-toptal @devstarman
Since KeyboardAvoidingView is a purely js implementation, you can work around this issue in the mean time by running your own KeyboardAvoidingView. Here is what I am currently using it is just a slightly modified version of the one in react-native.
https://gist.github.com/MitchellSlavik/0cf342af5711c36d69af5224dba1f7e5

All 19 comments

Have you found a solution to this?

Not really. I set the behaviour to height as it seems to work better sometimes, but it's not a solution.

I'm just waiting if a fix comes soon, otherwise I'll try rolling my own KeyboardAvoidingView.

After some digging, this looks like it was caused by the keyboardDidHide event getting actual values on Android #24947. KeyboardAvoidingView is assuming that event will come back with no value and it will set it's bottom state value to 0. The values in the keyboardDidHide event are those from View.getWindowVisibleDisplayFrame(), which is the visible frame of the device without the statusbar since anything under the status bar would not be visible to the user. This causes the KeyboardAvoidingView to think that there is a keyboard the height of the statusbar still on the screen and causes the white line at the bottom.

Have anyone found a solution for this issue?

Facing same issue on RN v0.60 and <StatusBar backgroundColor={'transparent'} translucent={true} />

Hi, is there any chance that this issue will be addressed soon?
I've switched to EXPO 36.0 recently and started to experience a lot of buggy behavior with KeyboardAvoidingView since :(

@Drzaln @dhruv-toptal @devstarman
Since KeyboardAvoidingView is a purely js implementation, you can work around this issue in the mean time by running your own KeyboardAvoidingView. Here is what I am currently using it is just a slightly modified version of the one in react-native.
https://gist.github.com/MitchellSlavik/0cf342af5711c36d69af5224dba1f7e5

I found that behavior="height" works fine and doesn鈥檛 leave the white space on the bottom.
However iOS works weird with behavior="height", so the solution is to use:

behavior={Platform.select({ android: "height", ios: "padding" })}

@hrastnik you are almost right but unfortunately, I found a bug with behavior="height" on Android and posted it here: https://github.com/facebook/react-native/issues/28004

Besides the whitespace, does anybody know a workaround on bottom tabs jumping when the keyboard closes?

@MitchellSlavik I actually have not noticed your suggestion and I'm pleased to report that it's working fabulously! Thank you very much! The question remains why nobody from react-native team checked this issue reported in multiple posts if the fix is available and only needs to be included into next official release as a fix.

@Drzaln @dhruv-toptal @devstarman
Since KeyboardAvoidingView is a purely js implementation, you can work around this issue in the mean time by running your own KeyboardAvoidingView. Here is what I am currently using it is just a slightly modified version of the one in react-native.
https://gist.github.com/MitchellSlavik/0cf342af5711c36d69af5224dba1f7e5

@MitchellSlavik did you or can you create a PR ?

Besides the whitespace, does anybody know a workaround on bottom tabs jumping when the keyboard closes?

if you are using @MitchellSlavik 's solution, I found that instead of using his _onKeyboardHide method, if you keep using _onKeyboardChange and replace , at the end of that method, this.setState({bottom: height}) with this.setState({bottom: Platform.OS === "ios" ? height : 0}), there is no jump

Not sure how this is related, but I noticed the KeyboardAvoidingView also has problems of height/padding restoration when changing orientation on android : rotating the phone from portrait to landscape and then back to portrait results in unwanted spacing at the bottom of the view.

Using @MitchellSlavik hack seems to resolve this issue too ! thanks a lot 馃檹

Also having this issue

Same problem with space on bottom of screen after upgrade RN from 0.60.6 to 0.61.0

While preparing the pull request for this issue I post the following:

https://github.com/facebook/react-native/pull/24947 normalized keyboardDidHide return value as following:

image

but the height returned in the below line does not include the StatusBar

image

https://github.com/facebook/react-native/blob/e23e9328aa164d0a70fe4f16042c982e7801d924/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java#L687

I changed the height to 900 in my case and the white bar does not show

I'm confident that I can publish pull request to fix this issue.

@MitchellSlavik is probably right saying that getWindowVisibleDisplayFrame does not include the StatusBar in the computation, this seems to be only applicable when using android:windowTranslucentStatus..

My current understanding is that windowTranslucentStatus makes the window show behind a translucent StatusBar, for this reason the window height is incrased by the StatusBar height.

I'll will find a solution for this issue and publish the pull request within days.

Thanks. Best Regards.

I was working on a pure JS RN app so the approach of @MitchellSlavik was not suitable for me.
If you have the same 'problem' this package saved my life:
https://www.npmjs.com/package/react-native-keyboard-aware-scroll-view

@MitchellSlavik Your implementation is not consistent in Android. Works on API 28 but not 29.

Was this page helpful?
0 / 5 - 0 ratings