skip to Main Content

I’m trying to create a view combining a FlatList with a View containing TextInput. I want the View containing the TextInput to sit at the bottom of the screen, with the FlatList occupying the remainder of the screen space. When you tap to enter text in the TextInput, I’d like the view to move upwards with the keyboard and overlap the FlatList contents – the sort of behaviour you’d usually see in a messaging screen on an app.

I’ve got the following code:

import React from 'react';
import { FlatList, KeyboardAvoidingView, Platform, SafeAreaView, Text, TextInput, View } from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons';

function Messages() {
    return (
        <KeyboardAvoidingView
            style={{
                flex: 1,
                justifyContent: "center",
            }}
            behavior={Platform.OS === 'ios' ? 'padding' : 'height'}>
            <SafeAreaView style={{ flex: 1, flexDirection: "column" }}>
                <FlatList
                    data={[1, 2, 3]}
                    renderItem={() => <Text>test</Text>}
                />
                <View style={{
                    flexDirection: "row",
                }}>
                    <TextInput
                        style={{
                            height: "auto",
                            margin: 5,
                            borderWidth: 1,
                            padding: 5,
                            flex: 1,
                        }}
                    />
                    <Icon
                        name={"send"}
                        size={25}
                    />
                </View>
            </SafeAreaView>
        </KeyboardAvoidingView>
    );
}

export default Messages;

However, the TextInput seems to always hide behind the keyboard rather than move with the keyboard. Does anyone know what I’m doing wrong?

2

Answers


  1. The problem is with SafeAreaView. You have placed it inside of your KeyboardAvoidingView. Ideally, all of your components must be nested inside of SafeAreaView and not the other way around.

    import React from "react";
    import {
      FlatList,
      KeyboardAvoidingView,
      Platform,
      SafeAreaView,
      Text,
      TextInput,
      View,
    } from "react-native";
    import Icon from "react-native-vector-icons/Ionicons";
    
    function App() {
      return (
        <SafeAreaView style={{ flex: 1, flexDirection: "column" }}> // Keep it as parent
          <KeyboardAvoidingView
            style={{
              flex: 1,
              justifyContent: "center",
            }}
            behavior={Platform.OS === "ios" ? "padding" : "height"}
          >
            <FlatList data={[1, 2, 3]} renderItem={() => <Text>test</Text>} />
            <View
              style={{
                flexDirection: "row",
              }}
            >
              <TextInput
                style={{
                  height: "auto",
                  margin: 5,
                  borderWidth: 1,
                  padding: 5,
                  flex: 1,
                }}
              />
              <Icon name={"send"} size={25} />
            </View>
          </KeyboardAvoidingView>
        </SafeAreaView>
      );
    }
    
    export default App;
    

    The rest of your code is fine.
    Here’s the snack.

    Login or Signup to reply.
  2. import React from 'react';
    import { ScrollView, KeyboardAvoidingView, Platform, SafeAreaView, Text, TextInput, View } from 'react-native';
    import Icon from 'react-native-vector-icons/Ionicons';
    
    function Messages() {
        return (
            <KeyboardAvoidingView
                style={{ flex: 1, justifyContent: "center" }}
                behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
            >
                <SafeAreaView style={{ flex: 1 }}>
                        {/* FlatList contents */}
                        {Array.from({ length: 50 }, (_, index) => (
                            <Text key={index}>Item {index}</Text>
                        ))}
    
                        <View style={{ flexDirection: "row", alignItems: "center" }}>
                            <TextInput
                                style={{
                                    height: "auto",
                                    margin: 5,
                                    borderWidth: 1,
                                    padding: 5,
                                    flex: 1,
                                }}
                            />
                            <Icon name={"send"} size={25} />
                        </View>
                    </ScrollView>
                </SafeAreaView>
            </KeyboardAvoidingView>
        );
    }
    
    export default Messages;
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search