theDC
theDC

Reputation: 6484

How to use KeyboardAvoidingView with FlatList?

I have a FlatList component with an Input inside each row. When I select the input I want it to scroll up above the keyboard.

My code:

return (
  <KeyboardAvoidingView behavior='padding' style={{ flex: 1 }} >
    <FlatList
      style={{ flex: 1, backgroundColor: '#fff' }}
      data={ds}
      renderItem={({ item }) => <ListItem data={item} />}
      ListFooterComponent={this.renderButton}
    />
  </KeyboardAvoidingView>
);

In this scenario, the FlatList is never loaded. When I delete flex:1 from both components, FlatList renders properly but selecting an Input does not make it scroll up

Upvotes: 34

Views: 36028

Answers (7)

Zeeshan Ansari
Zeeshan Ansari

Reputation: 10848

I used keyboardVerticalOffset and it fixed my issue

<KeyboardAvoidingView
      style={styles.keyboardAvoidingView}
      keyboardVerticalOffset={Platform.OS === 'ios' ? 110 : 0}
      behavior={Platform.OS === 'ios' ? 'padding' : 'height'}>

Upvotes: 1

Nitin
Nitin

Reputation: 1

Change 3 things:

  • Don't wrap FlatList inside KeyboardAvoidingView.
  • Wrap ListItem inside KeyboardAvoidingView.
  • Don't include behavior and style in KeyboardAvoidingView.

Upvotes: 0

iDevAmit
iDevAmit

Reputation: 1578

This would work, please try on:

<KeyboardAvoidingView behavior='position' keyboardVerticalOffset={x}  >

You can remove the property 'keyboardVerticalOffset' or keep it and play with the value of x, you just find out the value which fits in your case.

Upvotes: 14

JOONGYU HAN
JOONGYU HAN

Reputation: 11

this is my solution.
inverted={true} is the key

const dummy = [1,2,3,4,5,6,7,8,9,10]

<KeyboardAvoidingView > 
       <FlatList
            data={dummy.reverse()}
            inverted={true}
         />
</KeyboardAvoidingView>

Upvotes: -1

GenericJam
GenericJam

Reputation: 3015

For anyone on a similar path as mine. I was not able to use KeyboardAvoidingView because it depends on ScrollView which conflicts with Flatlist. I couldn't used the header and footer option in Flatlist as I'm using it as a generated thing in a search selection box so it has to be contained.

For me there is a difference in how Android and iOS calculate absolute position. Android considers the bottom to be the top of the keyboard and iOS it is the bottom of the screen when the keyboard is showing.

It turns out to be not that difficult to just put a View around the content you want to remain above the keyboard and just dynamically set the height of it on iOS. This isn't even really necessary on Android as it follows the keyboard if the View is position: absolute and bottom: 0.

This heavily borrows from here: https://stackoverflow.com/a/60682069/438322 Thanks to Kevin Amiranoff

Here's a basic example using hooks.

function YourComponent(props){
  const onKeyboardWillShow = e => {
    setKeyboardHeight(e.endCoordinates.height);
  };

  const onKeyboardWillHide = () => {
    setKeyboardHeight(0);
  };

  useEffect(() => {
    // These listeners on ios are a little more snappy but not available on Android
    // If you want to use this on Android use keyboardDidShow/Hide
    if (Platform.OS === 'ios') {
      Keyboard.addListener('keyboardWillShow', onKeyboardWillShow);
      Keyboard.addListener('keyboardWillHide', onKeyboardWillHide);
    }

    return () => {
      if (Platform.OS === 'ios') {
        Keyboard.removeListener('keyboardWillShow', onKeyboardWillShow);
        Keyboard.removeListener('keyboardWillHide', onKeyboardWillHide);
      }
    };
  }, []);

  const buttonHeight = 50;

  return(
    <View>
      <Content bla={'bla'}/>

      <View style={{
        height: Platform.OS === 'ios' 
          ? keyboardHeight + buttonHeight : buttonHeight, 
        position: 'absolute', 
        bottom: 0 
      }}>
      {/* Keep this button above the keyboard */}
      <Button style={{ height: buttonHeight }}/>
</View
    </View>
  )
}

Upvotes: 3

Rick Lam
Rick Lam

Reputation: 246

You can trying using react-native-keyboard-aware-scroll-view

https://github.com/APSL/react-native-keyboard-aware-scroll-view

It comes with KeyboardAware[ScrollView, ListView, SectionView, FlatList] which accepts the same props as their corresponding components from RN. I have used that and it worked for me.

render() {
  return (
  <KeyboardAwareFlatList
      style={{flex: 1}}
      data={this.state.data}
      renderItem={({item}) => (
        <View style={{flex: 1}}>
        <Image
          source={item.v}
          style={{height:200, width: 200}}
        />
        <TextInput
          placeholder="enter text1"
        />
        </View>

      )}
    />
  );
}

Upvotes: 20

Martin Konicek
Martin Konicek

Reputation: 40924

You could try using the library react-native-keyboard-spacer as an alternative to KeyboardAvoidingView.

Install:

npm install --save react-native-keyboard-spacer

Use it like this:

import KeyboardSpacer from 'react-native-keyboard-spacer'

...

<View style={{flex: 1}}>
  <FlatList
    style={{flex: 1}}
    data={ds}
    renderItem={({ item }) => <ListItem data={item} />}
  />

  {/* The view that will expand to match the keyboard height */}
  <KeyboardSpacer />
</View>

Upvotes: 17

Related Questions