I have a view below flatlist. I want the view to be always at bottom of screen and it is wrapped inside KeyboardAvoidingView. Check video for more details
https://drive.google.com/file/d/1eeMfpH3AV7AqLNqAhlhQX5JmOQSRLbtp/view?usp=sharing
As soon as I comment my FlatList code then the bottom view does not flicker.
Below is my code
<View>
<FlatList ..../>
<KeyboardAvoidingView
behavior={Platform.OS == "ios" ? "padding" : "height"}
>
<SafeAreaView style={styles.bottomViewStyle}>
<TouchableOpacity>
<Image source={CAMERA_CHAT_ICON} />
</TouchableOpacity>
<View style={styles.textAreaViewStyle}>
<TextInput
placeholder="Start Typing..."
placeholderTextColor="#9b9b9b"
style={styles.textInputStyle}
/>
</View>
<TouchableOpacity>
<Image source={CHAT_SEND_ICON} />
</TouchableOpacity>
</SafeAreaView>
</KeyboardAvoidingView>
</View>
All components including the FlatList component should be wrapped inside the KeyboardAvoidingView. Also, SafeAreaViews should be placed at the root of the screen because it provides padding for SafeAreas.
<KeyboardAvoidingView behavior={Platform.OS == "ios" ? "padding" : "height"}>
<SafeAreaView>
<FlatList ... />
<View>
<TextInput ... />
</View>
</SafeAreaView>
</KeyboardAvoidingView>
See https://reactnative.dev/docs/keyboardavoidingview and https://reactnative.dev/docs/safeareaview for more examples.
Related
Why my keyboard covers up my modal when I am focusing on my textinput ?
Code:
<BottomSheetModal
ref={ref}
index={1}
snapPoints={snapPoints}
handleIndicatorStyle={[s.handleStyle, s.handleColorWhite]}
backdropComponent={BottomSheetBackdrop}
>
<KeyboardAwareScrollView keyboardShouldPersistTaps='handled' contentContainerStyle={{flexGrow: 1}}>
<View style={s.centered}>
<Text style={s.title}>Rabatt-Code</Text>
<Text style={s.subtitle}>Füge ein Rabatt-Code für dein Produkt ein</Text>
<Text style={s.stepText}>{`Schritt ${step}/3`}</Text>
</View>
<Text style={[s.text, s.bold]}>Nur Buchstaben & Zahlen!</Text>
<View style={s.content}>
<View style={s.inputContainer}>
<Input
placeholder='Name (exp. Max50)'
value={coupon.name}
onChangeText={handleChangeName}
style={[InputStyles.full_icon]}
icon={<Ionicons name="md-newspaper-outline" size={24} style={s.icon} color="#333" />}
/>
</View>
<View style={s.containerInner}>
<Pressable onPress={handleChangeStage} style={[ButtonStyles.full]}>
<Text style={s.btnText}NEXT</Text>
</Pressable>
</View>
</View>
</KeyboardAwareScrollView>
</BottomSheetModal>
Anyone can explain me what I am doing wrong ? On Android its fine, this is only on iOS.
if you are using react-native-bottom-sheet look at this page https://gorhom.github.io/react-native-bottom-sheet/keyboard-handling/
Try wrapping BottomSheetModal in KeyboardAvoidingView and remove KeyboardAwareScrollView
You may need to use keyboardVerticalOffset to adjust
<KeyboardAvoidingView behavior={'height'} style={{flex:1}}>
<BottomSheetModal
ref={ref}
index={1}
snapPoints={snapPoints}
handleIndicatorStyle={[s.handleStyle, s.handleColorWhite]}
backdropComponent={BottomSheetBackdrop}
>
.....
<BottomSheetModal />
</KeyboardAvoidingView>
In general the lay-out seems fine, the content is wrapped up inside a KeyboardAvoidingView as followed:
<KeyboardAvoidingView
keyboardVerticalOffset={-useHeaderHeight()}
behavior={"padding"}
style={styles.container}>
<View style={styles.conversationContainer}>
<ScrollView
ref={scrollViewRef}
onContentSizeChange={() => scrollViewRef.current.scrollToEnd({ animated: true })}
overScrollMode='never'
showsVerticalScrollIndicator={false}
enableOnAndroid={true}
style={styles.conversation}>
{messagesView}
</ScrollView>
<View
style={styles.send}>
<TextInput
value={text}
textAlignVertical='center'
placeholder='Write your message'
style={styles.textInput}
blurOnSubmit={true}
onChangeText={(value) => setText(value)}
>
</TextInput>
<TouchableOpacity
style={[styles.button]}
activeOpacity={.6}
onPress={() => addMessage()}>
<IonIcon
name={"arrow-forward-circle-outline"}
size={30}
color={'#00966E'}
style={styles.icon} />
</TouchableOpacity>
</View>
</View>
</KeyboardAvoidingView>
With the keyboard open, the TextInput is placed above the keyboard as intended.
Keyboard Picture
But whenever I press a single keystroke, the entire view (including the TextInput), lowers down, covering half of the TextInput.
Image of keyboard covering the TextInput
I have already tried changing the KeyboardVerticalOffset to different values as well as the changing the behavior to "heigth", "position" or none. None of these happened to change anything.
Had the same issue. This syntax helped me: <KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}>
i'm working on a react native app and i updated my react version.
I use Flatlist inside a ScrollView.
I got this warning :
VirtualizedLists should never be nested inside plain ScrollViews with the same orientation - use another VirtualizedList-backed container instead.
My component :
return (
<KeyboardAvoidingView behavior="padding" enabled style={styles.keyboardAvoidingView}>
<SafeAreaView style={styles.keyboardAvoidingView}>
<Header
..
}}
containerStyle={styles.headerContainer}
rightComponent={{
...
}}
/>
<ScrollView style={styles.body}>
<View style={styles.titleSection}>
<Text style={styles.stepTitle}>Étape 1/3</Text>
<Text style={styles.questionTitle}>Quel contact voulez-vous partager ?</Text>
</View>
<View>
<FlatList
data={contacts}
renderItem={({ item, index }) => (
<TouchableHighlight onPress={() => this.onItemClickHandler(index, item.id, item.firstName, item.lastName)} style={styles.touchableHighlight}>
<View>
<ListItem
chevron={
(
<Icon
color={this.state.selectedIndex === index
? `${defaultTheme.palette.white.main}`
: `${defaultTheme.palette.primary.dark}`}
name="chevron-right"
size={40}
type="material"
/>
)
}
containerStyle={
this.state.selectedIndex === index
? styles.selected
: styles.notSelected
}
leftElement={
(
<Icon
...
/>
)
}
title={`${item.firstName} ${item.lastName}`}
titleStyle={this.state.selectedIndex === index
? [styles.titleStyle, styles.titleSelected]
: [styles.titleStyle, styles.defaultTitle]}
/>
</View>
</TouchableHighlight>
)}
extraData={this.state.selectedIndex}
keyExtractor={(item) => item.email}
ListHeaderComponent={this.renderHeader(searchValue)}
style={styles.flatListStyle}
ListFooterComponent={this.renderFooter}
/>
{
(contacts.length > 0 && page > 0)
&& <CustomButton title="Afficher la suite" onPress={() => this.makeRemoteRequest()} loading={loading} disabled={loading} />
}
</View>
</ScrollView>
</SafeAreaView>
</KeyboardAvoidingView>
);
I had the same issue. See my code
What I did is the component which I wanted to render outside the flatlist I included that inside the ListHeaderComponent and removed the Scrollview component. Now its working fine without any warning.
Below is the previous code:
<ScrollView >
<ReadCard data={this.state.data}/>
<FlatList
data={this.state.data.related}
keyExtractor={this._keyExtractor}
renderItem={this._renderItem}
ItemSeparatorComponent={ListSeprator}
/>
</ScrollView>
Below is the changed code without any warning:
<FlatList
data={this.state.data.related}
keyExtractor={this._keyExtractor}
renderItem={this._renderItem}
ItemSeparatorComponent={ListSeprator}
ListHeaderComponent={
<ReadCard data={this.state.data}/>
}
/>
I have a horizontal flatlist inside a vertical flatlist and I want data on the inside flatlist to be provided based on which item of the outer flatlist is being rendered
This is what I have currently:
<FlatList
style={styles.outerFlatlist}
data={this.state.catagories}
renderItem={({item, index})=>{
return (
<View>
<View>
<Text style={styles.catagoryName}>
{item.CategoryName}
</Text>
</View>
<View style={styles.innerFlatlist}>
<FlatList
horizontal={true}
data={this.state.product1}
renderItem={({item, index})=>{
return (
<View
style={styles.productsContainer}>
<View
style={styles.productImage}>
<Image
source={{uri:item.productImage}}
style={styles.image}
resizeMode='contain'>
</Image>
</View>
<View style={styles.productDETAILS}>
<Text
style={styles.productPrice}>R{item.productPrice}
</Text>
<Text
style={styles.productDescription}>
{item.productDecription}
</Text>
</View>
</View>
);
}}/>
</View>
</View>
);
}}/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
With the above code, everything works well except that each category displays the same data (this.state.product1), how can I make the data of the inner flatlist be dependant on the which item on the outer flatlist is displayed?
When you are inside the .map you already are inside the this.state.catagories , but since you always use this.state.product1 for the flatlist2 you will always get the same result because this.state.product1 stays the same.
At flatlist2 change the data to item.products or item.whateverYouNeedHereButArray
<View style={styles.innerFlatlist}>
<FlatList
horizontal={true}
data={item}
I am trying design like below image with react native.If anyone have worked like this modal design over the toolbar then please help me.
1
You will need a Modal with a embedded TouchableOpacity combined with some styling for positioning.
Please refer this
https://snack.expo.io/SJrDAC8Qr
render() {
return (
<>
<View>
<Appbar.Header>
<Appbar.Content title="Title" subtitle="Subtitle" />
<Appbar.Action icon="search" onPress={() => this.setState({displayModal: true})} />
</Appbar.Header>
<View>
<Text>Main content!</Text>
</View>
</View>
{/*Modal code*/}
<Modal transparent={true} visible={this.state.displayModal}>
{/*Container .. clicking this closes the modal*/}
<TouchableOpacity style={{flex:1}} onPress={() => this.setState({displayModal:false})}>
<View style={{backgroundColor:'blue', position:'absolute', right:0, width:200, height: 200}}>
<Text style={{color:'#ffffff'}}>Hello World!</Text>
</View>
</TouchableOpacity>
</Modal>
</>
);
}
Not very nicely styled but I guess it does what you want