React Native - KeyboardAvoidingView with Sticky Footer

11,429

Solution 1

Are you using react-navigation? This might be affected by the header of the react-navigation. The height of the header is vary on different mobile screen size. You need to get the get the height of the header and pass into the keyboardVerticalOffset props.

import { Header } from 'react-navigation';

 <KeyboardAvoidingView
  keyboardVerticalOffset = {Header.HEIGHT + 20}
  style = {{ flex: 1 }}
  behavior = "padding" >

  <ScrollView>
    <TextInput/>
    <TextInput/>
    <TextInput/>
    <TextInput/>
    <TextInput/>
    <TextInput/>
  </ScrollView> 

</KeyboardAvoidingView>

Solution 2

My app uses react-navigation. So Toh Ban Soon's answer I ended up doing

import { KeyboardAvoidingView } from 'react-native';
import { Constants } from 'expo';
import { Header } from 'react-navigation';

<KeyboardAvoidingView behavior="padding" keyboardVerticalOffset = {Header.HEIGHT + Constants.statusBarHeight} style={[sharedStyles.container, {justifyContent: 'center'}]}>

... Input components...

</KeyboardAvoidingView>

There is an issue about it here https://github.com/react-navigation/react-navigation/issues/3971

Solution 3

Stumbled across the same issue and wasn't able to solve it using the KeyboardAvoidingView. But here is a good alternative solution:

constructor() {
    super();
    this.state = {
        bottomHeight: 0
    }
}
componentDidMount() {
    this.keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', this._keyboardDidShow.bind(this));
    this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', this._keyboardDidHide.bind(this));
}
componentWillUnmount() {
    this.keyboardDidShowListener.remove();
    this.keyboardDidHideListener.remove();
}

_keyboardDidShow(e) {
    this.setState({ bottomHeight: e.endCoordinates.height - 50 })
}

_keyboardDidHide() {
    this.setState({ bottomHeight: 0 })
}

render() {
    return (
        <View style={{ flex: 1 }} behavior="padding">
            <View style={{ flex: 1, }}>
                <TextInput
                    placeholder="Username"
                    value={this.state.username}
                    style={Styles.textInput}
                    onChangeText={(username) => this.setState({ username })}
                    autoCorrect={false}
                />
                <TextInput
                    style={Styles.textInput}
                    placeholder="Email"
                    value={this.state.email}
                    onChangeText={(email) => this.setState({ email })}
                    autoCorrect={false}
                />
            </View>
            <View style={{ height: 100, backgroundColor: 'blue', position: 'absolute', left: 0, right: 0, bottom: this.state.bottomHeight }}>
                <Text>Submit</Text>
            </View>
        </View>

Hope this helps...

Share:
11,429

Related videos on Youtube

Thomas
Author by

Thomas

I'd build my house with Javascript if I could

Updated on September 15, 2022

Comments

  • Thomas
    Thomas over 1 year

    I'm trying to make a sticky footer with the KeyboardAvoidingView component in React Native. I'm very close to accomplishing this task, however, when they keyboard comes up, the footer is moving up but shrinking in height at the same time.

    Here's what it looks like before the keyboard comes up:

    enter image description here

    And here's what it looks like after the keyboard comes up:

    enter image description here

    As you can see, the submit container is smaller than it is before there is a keyboard.

    Here's my current code:

    render() {    
      return (
        <KeyboardAvoidingView style={{ flex: 1 }} behavior="padding">
          <View style={{ flex: 1, }}>
            <TextInput
              placeholder="Username"
              value={this.state.username}
              style={Styles.textInput}
              onChangeText={(username) => this.setState({ username })}
              autoCorrect={false}
            />
            <TextInput
              style={Styles.textInput}
              placeholder="Email"
              value={this.state.email}
              onChangeText={(email) => this.setState({ email })}
              autoCorrect={false}
            />
          </View>
          <View style={{ height: 100, backgroundColor: 'blue' }}>
            <Text>Submit</Text>
          </View>
        </KeyboardAvoidingView>
      );
    

    What am I doing wrong?

  • RandyTek
    RandyTek almost 4 years
    I tried the solution but the footer isn't moving up. The link you provided did not mention anything about this issue. Please do not promote your product here if it's not related with the question.