A React Native ScrollView component that resizes when the keyboard appears.
—
The KeyboardAwareFlatList is a FlatList component that automatically handles keyboard appearance by scrolling to keep focused TextInput fields visible. It extends React Native's FlatList with keyboard awareness capabilities, making it ideal for lists containing input fields.
A FlatList component enhanced with keyboard awareness functionality.
/**
* A FlatList component that automatically scrolls to keep focused TextInput fields visible
* when the keyboard appears. Extends FlatList with keyboard-aware behavior.
*/
export class KeyboardAwareFlatList<ItemT = any> extends React.Component<
KeyboardAwareFlatListProps<ItemT>,
KeyboardAwareState
> {
getScrollResponder(): any;
scrollToPosition(x: number, y: number, animated?: boolean): void;
scrollToEnd(animated?: boolean): void;
scrollForExtraHeightOnAndroid(extraHeight: number): void;
scrollToFocusedInput(
reactNode: any,
extraHeight?: number,
keyboardOpeningTime?: number
): void;
scrollIntoView(
element: React.ReactElement,
options?: ScrollIntoViewOptions
): Promise<void>;
update(): void;
}
interface KeyboardAwareFlatListProps<ItemT> extends KeyboardAwareProps, FlatListProps<ItemT> {}Usage Examples:
import React, { useState } from 'react';
import { View, TextInput, Text, StyleSheet } from 'react-native';
import { KeyboardAwareFlatList } from 'react-native-keyboard-aware-scroll-view';
interface Todo {
id: string;
text: string;
completed: boolean;
}
// Basic usage with input fields in list items
export function TodoList() {
const [todos, setTodos] = useState<Todo[]>([
{ id: '1', text: '', completed: false },
{ id: '2', text: '', completed: false },
{ id: '3', text: '', completed: false },
]);
const updateTodo = (id: string, text: string) => {
setTodos(prev => prev.map(todo =>
todo.id === id ? { ...todo, text } : todo
));
};
const renderTodoItem = ({ item }: { item: Todo }) => (
<View style={styles.todoItem}>
<TextInput
style={styles.todoInput}
placeholder="Enter todo item"
value={item.text}
onChangeText={(text) => updateTodo(item.id, text)}
/>
</View>
);
return (
<KeyboardAwareFlatList
data={todos}
renderItem={renderTodoItem}
keyExtractor={item => item.id}
style={styles.container}
enableOnAndroid={true}
extraHeight={75}
/>
);
}
// Advanced usage with form fields
export function UserProfileList() {
const [profiles] = useState([
{ id: '1', name: '', email: '', phone: '' },
{ id: '2', name: '', email: '', phone: '' },
{ id: '3', name: '', email: '', phone: '' },
]);
const renderProfileItem = ({ item, index }: { item: any, index: number }) => (
<View style={styles.profileItem}>
<Text style={styles.profileTitle}>Profile {index + 1}</Text>
<TextInput
style={styles.input}
placeholder="Name"
defaultValue={item.name}
/>
<TextInput
style={styles.input}
placeholder="Email"
defaultValue={item.email}
keyboardType="email-address"
/>
<TextInput
style={styles.input}
placeholder="Phone"
defaultValue={item.phone}
keyboardType="phone-pad"
/>
</View>
);
return (
<KeyboardAwareFlatList
data={profiles}
renderItem={renderProfileItem}
keyExtractor={item => item.id}
style={styles.container}
enableOnAndroid={true}
enableAutomaticScroll={true}
extraHeight={100}
extraScrollHeight={50}
keyboardOpeningTime={250}
resetScrollToCoords={{ x: 0, y: 0 }}
enableResetScrollToCoords={true}
ItemSeparatorComponent={() => <View style={styles.separator} />}
onKeyboardWillShow={(frames) => console.log('Keyboard will show', frames)}
/>
);
}
const styles = StyleSheet.create({
container: { flex: 1, backgroundColor: '#f5f5f5' },
todoItem: {
backgroundColor: 'white',
padding: 15,
marginVertical: 5,
marginHorizontal: 10,
borderRadius: 8,
},
todoInput: {
borderWidth: 1,
borderColor: '#ddd',
padding: 10,
borderRadius: 5,
},
profileItem: {
backgroundColor: 'white',
padding: 20,
marginVertical: 5,
marginHorizontal: 10,
borderRadius: 8,
},
profileTitle: {
fontSize: 16,
fontWeight: 'bold',
marginBottom: 10,
},
input: {
borderWidth: 1,
borderColor: '#ccc',
padding: 10,
marginBottom: 10,
borderRadius: 5,
},
separator: {
height: 1,
backgroundColor: '#eee',
},
});Gets the underlying FlatList's scroll responder for advanced scroll operations.
/**
* Get the underlying FlatList's scroll responder
* @returns The scroll responder instance
*/
getScrollResponder(): any;Programmatically scrolls to a specific position in the FlatList.
/**
* Scroll to specific position with or without animation
* @param x - The x coordinate to scroll to
* @param y - The y coordinate to scroll to
* @param animated - Whether to animate the scroll (default: true)
*/
scrollToPosition(x: number, y: number, animated?: boolean): void;Scrolls to the end of the FlatList content.
/**
* Scroll to end with or without animation
* @param animated - Whether to animate the scroll (default: true)
*/
scrollToEnd(animated?: boolean): void;Usage Example:
import React, { useRef } from 'react';
import { Button } from 'react-native';
import { KeyboardAwareFlatList } from 'react-native-keyboard-aware-scroll-view';
export function ScrollableFlatList({ data }: { data: any[] }) {
const flatListRef = useRef<KeyboardAwareFlatList>(null);
const scrollToTop = () => {
flatListRef.current?.scrollToPosition(0, 0, true);
};
const scrollToEnd = () => {
flatListRef.current?.scrollToEnd(true);
};
return (
<>
<KeyboardAwareFlatList
ref={flatListRef}
data={data}
renderItem={({ item }) => <YourItemComponent item={item} />}
keyExtractor={item => item.id}
/>
<Button title="Scroll to Top" onPress={scrollToTop} />
<Button title="Scroll to End" onPress={scrollToEnd} />
</>
);
}Android-specific method for scrolling with additional height offset.
/**
* Android-specific scroll method with extra height offset (Android only)
* @param extraHeight - Additional height to add to the scroll offset
*/
scrollForExtraHeightOnAndroid(extraHeight: number): void;Scrolls to a specific focused TextInput field within a list item.
/**
* Scroll to a specific focused input field
* @param reactNode - The React node handle of the input to scroll to
* @param extraHeight - Additional height offset (optional)
* @param keyboardOpeningTime - Custom keyboard opening delay (optional)
*/
scrollToFocusedInput(
reactNode: any,
extraHeight?: number,
keyboardOpeningTime?: number
): void;Scrolls a React element into view with customizable positioning.
/**
* Scrolls an element into view with customizable positioning
* @param element - The React element to scroll into view
* @param options - Configuration options for scroll positioning
* @returns Promise that resolves when scrolling is complete
*/
scrollIntoView(
element: React.ReactElement,
options?: ScrollIntoViewOptions
): Promise<void>;Manually triggers scrolling to the currently focused input field.
/**
* Manually trigger scroll to currently focused input
* Useful for updating scroll position after layout changes
*/
update(): void;The KeyboardAwareFlatList accepts all standard FlatList props plus the KeyboardAwareProps interface:
interface KeyboardAwareFlatListProps<ItemT> extends KeyboardAwareProps, FlatListProps<ItemT> {
// Inherits all FlatList props (data, renderItem, keyExtractor, etc.)
// Plus all KeyboardAwareProps (see main documentation)
}import React, { useState } from 'react';
import { View, TextInput, Button } from 'react-native';
import { KeyboardAwareFlatList } from 'react-native-keyboard-aware-scroll-view';
export function DynamicInputList() {
const [items, setItems] = useState([{ id: '1', value: '' }]);
const addItem = () => {
const newId = (items.length + 1).toString();
setItems([...items, { id: newId, value: '' }]);
};
const updateItem = (id: string, value: string) => {
setItems(items.map(item =>
item.id === id ? { ...item, value } : item
));
};
const renderItem = ({ item }: { item: { id: string, value: string } }) => (
<View style={{ padding: 10 }}>
<TextInput
placeholder={`Item ${item.id}`}
value={item.value}
onChangeText={(text) => updateItem(item.id, text)}
style={{ borderWidth: 1, padding: 10, borderRadius: 5 }}
/>
</View>
);
return (
<View style={{ flex: 1 }}>
<KeyboardAwareFlatList
data={items}
renderItem={renderItem}
keyExtractor={item => item.id}
enableOnAndroid={true}
extraHeight={75}
/>
<Button title="Add Item" onPress={addItem} />
</View>
);
}enableOnAndroid={true} and windowSoftInputMode="adjustPan" in AndroidManifest.xml for full functionalityInstall with Tessl CLI
npx tessl i tessl/npm-react-native-keyboard-aware-scroll-view