dv3
dv3

Reputation: 4579

React-native: How to control what keyboard pushes up

The structure of the app is fairly simple: A searchbar, a listview and react-native-tabs at the bottom. The problem: If I click on the searchbar on Android it pushes the whole app up, so I see the tabs directly over the keyboard. But on iOS the keyboard overlays the whole app, without pushing anything up. Is there any way to control that?
I'm happy to share code / screenshots if the question isn't clear.
Thanks

edit:

<View style={{flex:1, backgroundColor:'#f2f2f2'}}>
    <ListView
        dataSource={this.state.dataSource}
        renderRow={this.renderSearchResults.bind(this)}
        style={styles.listView}/>
    <KeyboardAvoidingView
        style={styles.addQuestionBar}
        behavior={'position'}>
        <Text>
            Don't see your question?
        </Text>
        <TouchableOpacity>
            <Text>
                Add it
            </Text>
        </TouchableOpacity>
    </KeyboardAvoidingView>
</View>

Upvotes: 106

Views: 155206

Answers (9)

sofronijev
sofronijev

Reputation: 57

I had a similar problem where the keyboard pushed one Text and a View component when the keyboard was up. I couldn't change the value of windowSoftInputMode it was set to adjustResize so I used this to fix it by putting them both inside

<KeyboardAvoidingView style={{flex: 1}} behavior="height" enabled={false}>

Upvotes: 0

Luis Pereira
Luis Pereira

Reputation: 350

According to many answers here (and in the similar topics), react-native Github issue and medium posts the issue cannot have only one solution/approach (I counted at least 4). And by the way, no one from this thread helped in my case. But the manual hiding did the job.

I use this hook in some places where default behaviour of RN/AwareScrollView don't work as expected.

export default function useIsKeyboardShown() {
const [isShown, setIsShown] = useState(false);

useEffect(() => {
   const keyboardDidShowSubscription = 
Keyboard.addListener('keyboardDidShow', () => {
  setIsShown(true);
});
const keyboardDidHideSubscription = 
Keyboard.addListener('keyboardDidHide', () => {
  setIsShown(false);
});

return () => {
  keyboardDidShowSubscription?.remove();
  keyboardDidHideSubscription?.remove();
};
 }, []);

return isShown;
}

like this for example:

 const isKeyboardShown = useIsKeyboardShown();
 <View
  style={[styles.outerBtnContainer, isKeyboardShown ? { height: 0 } : {}]}
 ></View>

Upvotes: 0

Samir
Samir

Reputation: 6617

I had the same issue while React Native - Javascript, SafeAreaView and ScrollView fix the problem

<SafeAreaView style={styles.container}>
    <ScrollView  > 
      <View style={styles.body}>
....

 container: {
    flex: 1,
    backgroundColor: 'white' 
  },

Upvotes: 0

kalyanrai
kalyanrai

Reputation: 21

****1) modify the AndroidMainfest.xml in android/src/main/AndroidMainfest.xml u can solve the issue by changing the

       $ android:windowSoftInputMode="adjustResize";
                       to  
       $ android:windowSoftInputMode="adjustPan";


          the problem will be resolvede****

Upvotes: 0

Abdulaziz Alkharashi
Abdulaziz Alkharashi

Reputation: 1316

There is new Component called KeyboardAvoidingView from React Native not documented yet but i already use it in my project and its very useful

Code Example:

'use strict'
import { ... , KeyboardAvoidingView } from 'react-native'

class Test extends Component {
  constructor () {
    super()
    this.state = {
      behavior: 'position' 
      // there is three ways to adjust (position , height , padding ) 
    }
  }
    


  render(){
    return (
        <View>
          <KeyboardAvoidingView behavior={this.state.behavior}>
            <TextInput
              style={style.PhoneNumberInput}
              onChangeText={(text) => this.setState({text})}
              value={this.state.text}
              />
          </KeyboardAvoidingView>
        </View>
    )
  }

}


module.exports = Test

and for more details you can check KeyboardAvoidingViewExample

EDIT:

Sorry i just got the wrong idea from the question i think what you are trying to do is stop the android keyboard from pushing the application up here is component that allow you to choose between (Pan, Resize, Nothing) in android

react-native-android-keyboard-adjust

Upvotes: 18

Shri ram
Shri ram

Reputation: 71

@binkie's answer worked for my expo (Version 44.0.0) app with a slight change. In app.json,

"android":{"softwareKeyboardLayoutMode": "pan"}

In the screen, margin bottom value equal to height of the bottom tab like so

<ScrollView mb="70px">...</ScrollView>

Upvotes: 0

Filip Savic
Filip Savic

Reputation: 3248

Use android:windowSoftInputMode="adjustResize".

KeyboardAvoidingView and other keyboard-related components don't work quite well if you have "adjustPan" set for your android:windowSoftInputMode in AndroidManifest.xml.

Instead, you should use "adjustResize" and have a wonderful life.

I had "adjustPan" and tried using KeyboardAvoidingView and KeyboardAwareScrollView... nothing worked.

Now, with "adjustResize", i'm not using any keyboard-related component and my android app works. (I might have to use KeyboardAvoiding view on iOS, but it will work out of the box.)

Upvotes: 2

binkie
binkie

Reputation: 995

For those using Expo

@J KW's answer is correct but if you're using Expo you will have to implement it differently.

Expo uses different configuration terms. In your app.json you have to set the configuration key "softwareKeyboardLayoutMode":"pan" in your android object. Your file might look something like:

{
  "expo": {
    "name": "App",
    ...
    "android":{"softwareKeyboardLayoutMode": "pan"},
    ...
  }
}

Note: If you are receiving a "should NOT have additional property" error, it's likely because you don't have the updated Expo SDK (v.038). Please update your Expo version.

Documentation: https://docs.expo.io/workflow/configuration/

Upvotes: 80

Jeph
Jeph

Reputation: 1798

Set android:windowSoftInputMode="adjustPan" in your manifest file, and it will work as you expect.

E.g.

<application
  android:name=".MainApplication"
  android:allowBackup="true"
  ...
  <activity
    android:name=".MainActivity"
    android:label="@string/app_name"
    ...
    android:windowSoftInputMode="adjustPan">
    ...
  </activity>
  ...
</application>

Upvotes: 167

Related Questions