Skip to main content
Version: 1.11.0

KeyboardAwareScrollView

ScrollView that effortlessly handles keyboard appearance, automatically scrolls to focused TextInput and provides a native-like performance.

Comparison​

Current react-native ecosystem has a plenty of solutions that solves the problem of focused inputs being covered by keyboard. Each of them has its own advantages and disadvantages.

Below is a table with the most important functions and their support in various implementations:

react-native-avoid-soft-inputreact-native-keyboard-aware-scroll-viewreact-native-keyboard-managerreact-native-keyboard-controller
Respects keyboard animation🟠 1❌✅✅
JS implementation❌✅❌🟠 2
Reacts on focused input layout changes❌❌🟠 3✅
Reacts on focus changes✅✅✅✅
Auto-scroll when user is typing and input in non visible area❌❌🟠 3✅
Android support✅✅❌✅
Maintained✅❌✅✅
Support Fabric (new) architecture✅🟠 4❌✅

1 only on iOS

2 KeyboardAwareScrollView is implemented in JS, but some hooks (useKeyboardHandler/useReanimatedFocusedInput/useFocusedInputHandler) exposed from native code

3 achievable with KeyboardManager.reloadLayoutIfNeeded() usage in appropriate TextInput callbacks (onLayout/onChangeText)

4 since it's JS based solution it supports new architecture, but it uses deprecated API.

Props​

ScrollView Props​

Inherits ScrollView Props.

bottomOffset​

The distance between keyboard and focused TextInput when keyboard is shown. Default is 0.

react-native-keyboard-aware-scroll-view equivalent

This property is equivalent to extraHeight from original react-native-keyboard-aware-scroll-view package.

disableScrollOnKeyboardHide​

Prevents automatic scrolling of the ScrollView when the keyboard gets hidden, maintaining the current screen position. Default is false.

enabled​

A boolean prop indicating whether KeyboardAwareScrollView is enabled or disabled. Default is true.

FlatList/FlashList/SectionList integrations​

Unlike original react-native-keyboard-aware-scroll-view package I'm not exporting KeyboardAwareFlatList, KeyboardAwareSectionList and other components.

If you want to integrate it with your custom virtualization list, you can pass renderScrollComponent prop like:

import { FlatList } from "react-native";
import { KeyboardAwareScrollView } from "react-native-keyboard-controller";

<FlatList
renderScrollComponent={(props) => <KeyboardAwareScrollView {...props} />}
/>;

// or

import { FlashList } from "@shopify/flash-list";

<FlashList
renderScrollComponent={(props) => <KeyboardAwareScrollView {...props} />}
/>;
Click to see a full code example with integration
import React from "react";
import { View, FlatList, TextInput } from "react-native";
import { KeyboardAwareScrollView } from "react-native-keyboard-controller";

const List = () => {
return (
<View style={{ flex: 1 }}>
<FlatList
data={new Array(10).fill(0).map((_, i) => i)}
keyExtractor={(data) => String(data)}
renderItem={() => {
return (
<View
style={{
width: "100%",
height: 250,
backgroundColor: "#00000066",
justifyContent: "center",
}}
>
<TextInput
style={{
height: 40,
width: "100%",
borderColor: "black",
borderWidth: 2,
}}
/>
</View>
);
}}
renderScrollComponent={(props) => (
<KeyboardAwareScrollView {...props} />
)}
ItemSeparatorComponent={() => <View style={{ height: 5 }} />}
showsVerticalScrollIndicator={false}
/>
</View>
);
};

export default List;

Example​

import React from "react";
import {
StyleSheet,
TextInputProps,
TextInput as TextInputRN,
} from "react-native";
import { KeyboardAwareScrollView } from "react-native-keyboard-controller";

const TextInput = (props: TextInputProps) => {
return (
<TextInputRN
placeholderTextColor="#6c6c6c"
style={styles.textInput}
multiline
numberOfLines={2}
testID={props.placeholder}
{...props}
placeholder={`${props.placeholder} (${
props.keyboardType === "default" ? "text" : "numeric"
})`}
/>
);
};

export default function AwareScrollView() {
return (
<KeyboardAwareScrollView
bottomOffset={50}
style={styles.container}
contentContainerStyle={styles.content}
>
{new Array(10).fill(0).map((_, i) => (
<TextInput
key={i}
placeholder={`TextInput#${i}`}
keyboardType={i % 2 === 0 ? "numeric" : "default"}
/>
))}
</KeyboardAwareScrollView>
);
}

const styles = StyleSheet.create({
container: {
paddingHorizontal: 16,
},
content: {
paddingTop: 50,
},
textInput: {
width: "100%",
minHeight: 50,
maxHeight: 200,
marginBottom: 50,
borderColor: "black",
borderWidth: 2,
marginRight: 160,
borderRadius: 10,
color: "black",
paddingHorizontal: 12,
},
});

Known issues​