Ref in flatlist items does not return correct PageY position when loading more data in a list - react-native

I am trying to display dropdown below flatlist items. Pagination is implemented in Flatlist, so when i load data for first-page, the dropdown position is calculated accurately. but when i load data for another pages, pageY postion in ref measure method is increased by list size. So due to this dropdown isn't displayed in visible area. I am attaching my code for reference.
this is my render method.
render() {
let { list, } = this.props;
const {top,listVisibity,articleDropdown} = this.state;
return (
<View style={{flex:1}}>
<OptimizedFlatList
maxToRenderPerBatch={10}
windowSize={16}
onEndReached={() => this.onEndReached()}
nestedScrollEnabled={false}
onScrollBeginDrag = {() => this.setState({listVisibity:false})}
onEndReachedThreshold={Platform.OS === 'ios' ? 0 : 0.01}
onMomentumScrollBegin={() => { this.onEndReachedCalledDuringMomentum = false; }}
data={list}
renderItem={({ item }) => this._renderItem(item)}
keyExtractor={item => item.id}
style={{ flexGrow: 1}}
ListFooterComponent={this.footer}
/>
</view>
}
And here is list and sublist rendering
_renderItem = item => {
return (
<View style={styles.container}>
<ShadowView style={styles.shadowStyle}>
<View style={styles.listItem} >
<View style={{ flex: 0.6, flexDirection: 'row' }}>
<Image
source={constants.images.dot}
style={{ alignSelf: 'center', width: RFValue(12), resizeMode: 'contain', marginRight: 10 }}
/>
<Highlighter
highlightStyle={{backgroundColor: 'yellow'}}
searchWords={[this.props.searchedText]}
textToHighlight= {item.name.toUpperCase()+" ("+item.topics.length+")"}
style={{ color: "#0C3C7F", alignSelf: 'center', fontWeight: '500', fontFamily:constants.fontFamily.SFProDisplay }}
/>
</View>
<View style={{ flex: 0.4}}>
<TouchableOpacity onPress={() => {
this.updateSelection(item)
}}>
{item.isExpanded ? <Image
source={constants.images.dropdownArrow}
style={{ alignSelf: 'flex-end', resizeMode: 'contain' }}
/> :
<Image
source={constants.images.arrowUp}
style={{ alignSelf: 'flex-end', resizeMode: 'contain' }}
/>
}
</TouchableOpacity>
</View>
</View>
</ShadowView>
{this.renderSubList(item)}
</View>
);
}
renderSubList = (item) => {
return <Collapsible collapsed={!item.isExpanded}>
<FlatList
data={item.topics}
scrollEnabled={false}
renderItem={({ item }) => (
<ShadowView style={item.isSelected? styles.topicShadowStyle_1:styles.topicShadowStyle}>
<View ref={ref => this.parentView = ref}
onLayout={(event) => {
this.find_dimesions(event.nativeEvent.layout) }}
style={[{flexDirection: 'row'}, item.isSelected ? { borderColor: constants.colors.lightBlue, borderTopLeftRadius: 10,borderBottomLeftRadius: 10,borderRadius:8, borderWidth: 2 } : {}]}>
{(item.fullTextUrl!=null && item.fullTextUrl!='') || (item.pdfLink!=null && item.pdfLink!='') ?
<View style={{ width: width * 4 / 100, backgroundColor: constants.colors.lightBlue, borderTopLeftRadius: 8, borderBottomLeftRadius: 8 }}></View>:
<View style={{ width: width * 4 / 100, backgroundColor: constants.colors.lightGray_1, borderTopLeftRadius: 8, borderBottomLeftRadius: 8 }}></View>
}
<View style={{ width: '95%' }}>
<TouchableWithoutFeedback onLongPress={() => this.props.updateShowSelectedIcon(item)} onPress={() => this.props.showDetails(item)}>
<View style={{ flexDirection: 'row', width: '100%' }}>
<View style={{ flex: 1, marginHorizontal: width * 3 / 100, marginVertical: height * 1.5 / 100, backgroundColor: constants.colors.white }}>
<View style={{ flexDirection: 'row', width: '100%' }}>
<View style={{ alignContent: 'flex-start', width: '65%' }}>
<Highlighter
highlightStyle={{backgroundColor: 'yellow'}}
searchWords={[this.props.searchedText]}
textToHighlight= {item.journal.toUpperCase()}
style={styles.jurnalTitle}
numberOfLines={2}
/>
</View>
<View style={{ alignContent: 'flex-end', width: '35%', }}>
<Text style={styles.dateStyle} >{item.date}</Text>
</View>
</View>
<View style={{ flexDirection: 'row', width: '100%', marginTop: height * 1 / 100 }}>
<View style={{ alignItems: 'flex-start', width: '70%' }}>
<Highlighter
highlightStyle={{backgroundColor: 'yellow'}}
searchWords={[this.props.searchedText]}
textToHighlight= {item.article}
style={{ fontWeight: 'bold', color: constants.colors.black_1, alignContent: 'flex-start' }}
numberOfLines={2}
/>
</View>
{!this.props.showSelectedIcon?
<View
ref={(ref) => { this.rowRefs[item.id] = ref; }}
// ref={ref => this[`myView${item.id}`]=ref}
onLayout={(event) => {
const {x, y, width, height} =event.nativeEvent.layout
}}
style={{position:'relative', alignItems: 'flex-end', width: '30%' }}>
<TouchableOpacity style={{ height: RFValue(20), width: RFValue(20) }}
onPress={() => this.calculateIconPosition(item)}>
{(item.fullTextUrl!=null && item.fullTextUrl!='') || (item.pdfLink!=null && item.pdfLink!='') ?
<Image
source={constants.images.Oval}
style={{ height: RFValue(20), width: RFValue(20) }}
/>:
<Image
source={constants.images.dropdown}
style={{ height: RFValue(20), width: RFValue(20) }}
/>
}
</TouchableOpacity>
{/* { <View onLayout={(event) => {
const {x, y, width, height} =event.nativeEvent.layout
console.log(y)
}} > </View>} */}
</View>:
<View
style={{ alignItems: 'flex-end', width: '30%' }}>
{item.isSelected?
<Image
source={constants.images.selected}
style={{ height: RFValue(20), width: RFValue(20) }}
/>:
<Image
source={constants.images.unselect}
style={{ height: RFValue(20), width: RFValue(20) }}
/>
}
</View>
}
</View>
</View>
</View>
</TouchableWithoutFeedback>
{this.renderNotesView(item)}
</View>
</View>
</ShadowView>
)}
keyExtractor={item => item.id}
/>
</Collapsible>
}
Item Measurement Method Call
calculateIconPosition = (item) => {
this.rowRefs[item.id].measure( (fx, fy, width, height, px, py) => {
console.log("=================PY=====================")
console.log(py)
})
}
Is there any way to get exact pageY position in flat list.

Related

Possible Unhandled promise rejection TypeError: Network request failed, cannot read property 'map' of undefined

Recently started learning react-native and I'm following this tutorial on youtube, I'm trying to fetch flags and country codes from some websites api but I'm getting an error saying
Possible Unhandled promise rejection TypeError: Network request
failed, cannot read property 'map' of undefined
import {
View,
Text,
TouchableOpacity,
TouchableNativeFeedback,
Image,
TextInput,
Modal,
FlatList,
KeyboardAvoidingView,
ScrollView
} from "react-native";
import React from "react";
import LinearGradient from "react-native-linear-gradient";
import { COLORS, SIZES, FONTS, icons, images } from "../constants"
const SignUp = () => {
const [showPassword, setShowPassword] = React.useState(false);
const [areas, setAreas] = React.useState([]);
const [selectedArea, setSelectedArea] = React.useState(null);
const [modalVisible, setModalVisible] = React.useState(false);
React.useEffect(() => {
fetch("https://restcountries.eu/rest/v3.1/all")
.then(response => response.json())
.catch(err => {
console.log(err);
})
.then((data) => {
let areaData = data.map(item => {
return {
code: item.alpha2Code,
name: item.name,
callingCode: `+${item.callingCodes[0]}`,
flag: `https://countryflagsapi.com/png/${item.alpha2code}`
}
}).catch(err => {
console.log(err);
});
setAreas(areaData)
if (areaData.length > 0) {
let defaultData = areaData.filter(a => a.code == "US")
if (defaultData.length > 0) {
setSelectedArea(defaultData[0])
}
}
})
}, [])
function renderHeader() {
return (
<TouchableOpacity
style={{
flexDirection: "row",
alignItems: "center",
marginTop: SIZES.padding * 2,
paddingHorizontal: SIZES.padding * 2
}}
onPress={() => console.log("SignUp")}
>
<Image
source={icons.back}
resizeMode="contain"
style={{
width: 20,
height: 20,
tintColor: COLORS.white
}}
/>
<Text
style={{ marginLeft: SIZES.padding * 1.5, color: COLORS.white, ...FONTS.h4 }}
>Sign Up</Text>
</TouchableOpacity>
)
}
function renderLogo() {
return (
<View
style={{
marginTop: SIZES.padding * 5,
height: 100,
alignItems: 'center',
justifyContent: 'center'
}}
>
<Image
source={images.wallieLogo}
resizeMode="contain"
style={{
width: "60%"
}}
/>
</View>
)
}
function renderForm() {
return (
<View
style={{
marginTop: SIZES.padding * 3,
marginHorizontal: SIZES.padding * 3,
}}
>
{/* Full Name */}
<View
style={{
marginTop: SIZES.padding * 3,
}}
>
<Text
style={{
color: COLORS.lightGreen, ...FONTS.body3
}}
>Full Name</Text>
<TextInput
style={{
marginVertical: SIZES.padding,
borderBottomColor: COLORS.white,
borderBottomWidth: 1,
height: 40,
color: COLORS.white,
...FONTS.body3
}}
placeholder="Enter Full Name"
placeholderTextColor={COLORS.white}
selectionColor={COLORS.white}
/>
{/* Phone Number */}
<View style={{ marginTop: SIZES.padding * 2 }}>
<Text style={{ color: COLORS.lightGreen, ...FONTS.body3 }}>Phone Number</Text>
<View style={{ flexDirection: "row" }}>
{/* Country Code */}
<TouchableOpacity
style={{
width: 100,
height: 50,
marginHorizontal: 5,
borderBottomColor: COLORS.white,
borderBottomWidth: 1,
flexDirection: "row",
...FONTS.body2
}}
onPress={() => console.log("Show Modal")}
>
<View style={{ justifyContent: "center" }}>
<Image
source={icons.down}
style={{
width: 10,
height: 10,
tintColor: COLORS.white,
}}
/>
</View>
<View style={{ justifyContent: "center", marginLeft: 7 }}>
<Image
source={{ uri: selectedArea?.flag }}
resizeMode="contain"
style={{
width: 30,
height: 30
}}
/>
</View>
<View style={{ justifyContent: "center", marginLeft: 7 }}>
<Text style={{ color: COLORS.white, ...FONTS.body3 }}>{selectedArea?.callingCode}</Text>
</View>
</TouchableOpacity>
{/* Phone Number Input */}
<TextInput
style={{
flex: 1,
marginVertical: SIZES.padding,
borderBottomColor: COLORS.white,
borderBottomWidth: 1,
height: 40,
color: COLORS.white,
...FONTS.body3
}}
placeholder="Enter Phone Number"
placeholderTextColor={COLORS.white}
selectionColor={COLORS.white}
/>
</View>
</View>
{/* Password */}
<View style={{ marginTop: SIZES.padding * 2 }}>
<Text
style={{
color: COLORS.lightGreen,
...FONTS.body3
}}
>Password</Text>
<TextInput
style={{
marginVertical: SIZES.padding,
borderBottomColor: COLORS.white,
borderBottomWidth: 1,
height: 40,
color: COLORS.white,
...FONTS.body3
}}
placeholder="Enter Password"
placeholderTextColor={COLORS.white}
selectionColor={COLORS.white}
secureTextEntry={!showPassword}
/>
<TouchableOpacity
style={{
position: "absolute",
right: 0,
bottom: 10,
height: 30,
width: 30
}}
onPress={() => setShowPassword(!showPassword)}
>
<Image
source={showPassword ? icons.disable_eye : icons.eye}
style={{
height: 20,
width: 20,
tintColor: COLORS.white
}}
/>
</TouchableOpacity>
</View>
</View>
</View>
)
}
function renderButton() {
return (
<View style={{ margin: SIZES.padding * 3 }}>
<TouchableOpacity
style={{
height: 60,
backgroundColor: COLORS.black,
borderRadius: SIZES.radius / 1.5,
alignItems: "center",
justifyContent: "center"
}}
onPress={() => console.log("Let's Go")}
>
<Text style={{ color: COLORS.white, ...FONTS.h3 }}>Continue</Text>
</TouchableOpacity>
</View>
)
}
return (
<KeyboardAvoidingView
behavior={Platform.OS === "ios" ? "padding" : null}
style={{ flex: 1 }}
>
<LinearGradient
colors={[COLORS.lime, COLORS.emerald]}
style={{ flex: 1 }}
>
<ScrollView>
{renderHeader()}
{renderLogo()}
{renderForm()}
{renderButton()}
</ScrollView>
</LinearGradient>
</KeyboardAvoidingView>
)
}
export default SignUp;
Saw an old post regarding this issue but the solution of adding catch(err didn't work please any suggestions
The problem you faced mainly occurs in the fetch() inside useEffect().
To handle the any potential errors in function, we will use catch() as #caslawter mentioned.
fetch("https://restcountries.eu/rest/v3.1/all")
.then(response => response.json())
.then((data) => {
//... Do what you want after fetch data
})
.catch(err => {
//Any error occurs in json parsing or after fetching data will jump to here
console.log(err);
})
Also, please make sure your data is not undefined before you apply 'map' function to it.

react-native-video inside flatlist showing black screen after scrolling some videos

I am developing a flatlist with full screen videos like tiktok, it works fine for first 16/17 videos then when I scroll further it shows black screen.
Following is my code for the flatlist:
<FlatList
style={{
width: width,
height: this.state.videoHeight,
}}
getItemLayout={(data, index) => ({
length: this.state.videoHeight,
offset: this.state.videoHeight * index,
index,
})}
onScrollToIndexFailed={(info) => {
const wait = new Promise((resolve) =>
setTimeout(resolve, 500),
);
wait.then(() => {
this.flatlistRef.current?.scrollToIndex({
index: info.index,
animated: false,
});
});
}}
showsVerticalScrollIndicator={false}
data={this.state.allVideos}
ref={this.flatlistRef}
scrollEnabled={!this.state.isMinimizePlayer}
viewabilityConfig={this.viewabilityConfig}
decelerationRate={0}
removeClippedSubviews={true}
snapToAlignment={'start'}
snapToInterval={this.state.videoHeight}
horizontal={false}
onViewableItemsChanged={this.onViewableItemsChanged}
renderItem={this.renderItem}
keyExtractor={(item, index) => item.id}
/>
Render function code
renderItem = ({item, index}) => (
<PlayerContext.Consumer>
{({setVideo, setMetaData}) => (
<TouchableOpacity
onPress={() => {
if (!this.state.isMinimizePlayer) {
this.setState({isPause: !this.state.isPause});
} else {
this.maximizePlayr();
}
}}
activeOpacity={0.9}
style={{
width: width,
height: this.state.videoHeight,
}}>
<Video
// hideShutterView={false}
// useTextureView={true}
ref={(ref) => {
this.playerRef[index] = ref;
}}
style={{
backgroundColor: 'black',
width: this.state.videoWidth,
height: this.state.videoHeight,
}}
resizeMode={'cover'}
muted={this.state.isMute}
paused={
index == this.state.currentVisibleIndex
? this.state.isPause
: true
// index !== this.state.currentVisibleIndex ||
// !this.state.isPause
}
onLoad={(data) => {
// console.log('===>' + index);
}}
controls={false}
hideShutterView={true}
repeat={this.state.isLoop}
onEnd={() => {
if (!this.state.isLoop) {
if (this.state.isAutoPlay) {
if (
this.state.currentVisibleIndex <
this.state.allVideos.length - 1
) {
if (this.state.setGoNext) {
this.setState({setGoNext: false});
this._goToNextPage();
setTimeout(() => {
this.setState({setGoNext: true});
}, 1000);
}
} else {
setVideo(null);
}
}
}
}}
onProgress={(progress) => {
if (this.state.currentTrackDuration == 0) {
this.setState({
currentTrackDuration: progress.seekableDuration,
});
}
this.setState({
progress: progress.currentTime / progress.seekableDuration,
});
}}
bufferConfig={{
minBufferMs: 15000,
maxBufferMs: 50000,
bufferForPlaybackMs: 1500,
bufferForPlaybackAfterRebufferMs: 1500,
}}
source={{uri: item.url}}
poster={item.url}
onError={(e) => console.log('video load failed!' + index, e)}
onVideoError={(e) =>
console.log('video error load failed!' + index, e)
}
onReadyForDisplay={() => {}}
posterResizeMode={'cover'}></Video>
{this.state.isMinimizePlayer && (
<View
style={{
backgroundColor: this.ThemedColors.happy,
position: 'absolute',
width: this.state.videoWidth,
justifyContent: 'center',
alignItems: 'center',
height: this.state.videoHeight,
}}>
<TouchableOpacity
onPress={() => {
this.setState({isPause: !this.state.isPause});
}}>
<IconM
name={!this.state.isPause ? 'play-arrow' : 'pause'}
size={28}
color={'white'}
/>
</TouchableOpacity>
</View>
)}
{this.state.isMinimizePlayer && (
<View
style={{
flexDirection: 'row',
flex: 1,
height: this.state.videoHeight,
justifyContent: 'space-between',
alignItems: 'center',
top: 0,
bottom: 0,
left: 110,
position: 'absolute',
right: 10,
}}>
<View
style={{
flex: 1,
paddingHorizontal: 10,
justifyContent: 'center',
}}>
<Text style={{}} numberOfLines={1}>
{item.name}
</Text>
<View
style={{
marginTop: 5,
flexDirection: 'row',
paddingLeft: 0,
alignItems: 'center',
}}>
<Image
source={require('../../../assets/Images/icon_eye.png')}
style={{
height: 10,
width: 16,
tintColor: 'black',
resizeMode: 'contain',
}}
/>
<Text style={{marginLeft: 2}}>{this.metaData.from}</Text>
</View>
</View>
<TouchableOpacity
onPress={() => {
setVideo(null);
}}
style={{
height: 50,
width: 50,
alignItems: 'center',
justifyContent: 'center',
}}>
<Icon name="close" size={20} color={'black'} />
</TouchableOpacity>
</View>
)}
{!this.state.isMinimizePlayer && (
<LinearGradient
colors={['#000000', '#80000000']}
style={{
position: 'absolute',
top: 0,
paddingTop: Platform.OS == 'ios' ? width * 0.1 : width * 0.04,
left: 0,
right: 0,
}}>
<Text style={this.ThemedStyles.videoTitleText} numberOfLines={1}>
{item.name}
</Text>
<View style={this.ThemedStyles.videoMomentContaine}>
<Text style={this.ThemedStyles.videoDateText}>
{moment.unix(item.createdAt / 1000).format('MMMM DD, YYYY')}
</Text>
<Text
style={[
this.ThemedStyles.videoMomentText,
{backgroundColor: this.ThemedColors[item.moment]},
]}>
{item.moment}
</Text>
</View>
<View style={this.ThemedStyles.videoMomentTagContaine}>
{item?.tagN?.map((data) => {
return (
<View>
<Text style={this.ThemedStyles.videoDateText}>
#{data}
</Text>
</View>
);
})}
</View>
</LinearGradient>
)}
</TouchableOpacity>
)}
</PlayerContext.Consumer>
);
When scrolling it works and playing videos for first 16 videos then it show black screen for next videos and not playing them. When scrolling back to previous videos they are still playing but videos after 16th are black.

FlatList not visible even if i added it in React Native

I have added searchview then another row below that and then i have added flatlist in my view below the horizontal listview and i want to show it in full remaining height but it is not showing, there is also not any error in the code and also it doesn't show any error in console, here is a code :
<View style={styles.mainContainer}>
<View style={styles.searchView}>
<TextInput
style={styles.searchInput}
onChangeText={text => this.SearchFilterFunction(text)}
value={this.state.searchText}
underlineColorAndroid="transparent"
placeholder="Search Services"
placeholderTextColor={theme.colors.app_blue_light}
/>
<Image source={Images.search} style={styles.searchImage} />
</View>
{/* MapView */}
<View style={styles.MapToggleContainer}>
<Text style={styles.titleShop}>Select your shop</Text>
<Text style={styles.titleToggle}
onPress={this.toggleView}>List View</Text>
</View>
<View style={styles.shopListView}>
<FlatList
horizontal
style={styles.shopsList}
data={this.state.data}
renderItem={({ item: rowData }) => {
return (
<View style={styles.shopListItem}>
<Image source={require('./logo.png')} style={styles.shopImage} />
</View>
);
}}
keyExtractor={(item, index) => index}
/>
</View>
<MapboxGL.MapView>
<MapboxGL.Camera centerCoordinate={this.state.coordinates[0]} zoomLevel={14} />
<MapboxGL.MarkerView id='marker1' coordinate={this.state.coordinates[0]}>
<ImageBackground source={require('./chat.png')}
style={{ borderColor: 'black', borderWidth: 0, width: 80, height: 80, alignContent: 'center' }}>
<TouchableOpacity style={{ width: '100%', height: '100%', alignItems: 'center', justifyContent: 'center' }}
onPress={() => {
this.setState({ toolTipVisible: true })
}}>
<Tooltip
animated
isVisible={this.state.toolTipVisible}
content={<View style={{ width: '100%', height: '100%', backgroundColor: 'white' }}>
<View style={{ flexDirection: 'row' }}>
<Image source={require('./chat.png')} />
<View style={{ flexDirection: 'column' }}>
<Text style={{ marginHorizontal: 10, marginTop: 10 }}>123, Main st,</Text>
<Text style={{ marginHorizontal: 10, marginBottom: 10 }}>Chicago, IL 6061</Text>
</View>
</View>
<TouchableOpacity
style={{ backgroundColor: 'orange', margin: 10, alignItems: 'center' }}
onPress={() => { }}
>
<Text style={{ margin: 10, color: 'white' }}>Select Shop</Text>
</TouchableOpacity>
</View>}
placement="top"
onClose={() => this.setState({ toolTipVisible: false })} >
<Text style={{ color: 'white', fontWeight: 'bold', fontSize: 20 }} >$50.00</Text>
</Tooltip>
</TouchableOpacity>
</ImageBackground>
</MapboxGL.MarkerView>
</MapboxGL.MapView>
</View>
Styles
mainContainer: {
flex: 1,
backgroundColor: theme.colors.white
},
toggleContainer: {
flexDirection: 'row',
justifyContent: 'space-between',
marginTop: '20#ms',
marginBottom:'10#ms',
marginHorizontal: '15#ms',
},
titleShop: {
fontFamily: 'Muli-Bold',
fontSize: '16#ms',
color: theme.colors.gray4
},
titleToggle: {
fontFamily: 'Muli-Bold',
fontSize: '11#ms',
color: theme.colors.gray4,
textDecorationLine: 'underline',
alignSelf:'center'
},
MapToggleContainer:{
flexDirection: 'row',
justifyContent: 'space-between',
marginTop: '10#ms',
marginBottom:'15#ms',
marginHorizontal: '15#ms',
},
shopListView:{
height:'60#ms'
},
shopsList:{
marginLeft:'5#ms',
marginRight:'15#ms',
},
shopListItem:{
elevation:5,
backgroundColor:'white',
marginLeft:'10#ms',
height:'50#ms',
width:'50#ms',
alignItems:'center',
justifyContent:'center',
borderRadius:'5#ms'
},
shopImage:{
width:'30#ms',
height:'30#ms',
},
And here is a result, as you can see the mapview below list is not visible
give height and width style to MapboxGL.MapView
<MapboxGL.MapView style={{width:Dimensions.get("window").width,height:400}}>

React native flatlist leaves empty spaces, for items that don't match conditions

The first row shows a single card, this is because the item suppose to be there doesn't match the condition stated. But I want to remove this space, and put the next card which is currently on the next line there.
{state.data ? <FlatList
data={state.data}
renderItem={({ item }) => {
console.log(item)
return (
<View style={{ justifyContent: 'space-evenly', marginHorizontal: 0 }}>
<View>
{item.available == 1 ?
<TouchableOpacity activeOpacity={.8} onPress={() => navigation.navigate('Appointment', { id: item.id, name: item.name, phone: item.phone, email: item.email, session: item.session, player_id: item.player_id, picture: item.picture })} >
<Card style={{ width: width / 2.05, alignItems: 'center', justifyContent: 'center', borderRadius: 15, paddingTop: 10, height: height / 2.4 }}>
<CardItem cardBody>
<Image
source={{ uri: 'http://example.com/storage/' + item.picture }}
style={{ height: 200, width: null, flex: 1 }}
/>
</CardItem>
<CardItem>
<Text> {item.name} </Text>
</CardItem>
</Card>
</TouchableOpacity>
: null}
</View>
</View>
)
}}
numColumns={2}
/> : <ActivityIndicator size="large" style={{ alignItems: 'center', justifyContent: 'center', flex: 1, flexDirection: 'row' }} />}
The null value just shows that empty space, is there a way to completely remove this empty space?
You need to filter your data. Otherwise, your code will create empty Views.
Try to filter your data as follows.
It would be good if you move this filter logic from your render method.
{state.data ? <FlatList
data={state.data.filter(item => item && item.available === 1)}
renderItem={({ item }) => {
return (
<View style={{ justifyContent: 'space-evenly', marginHorizontal: 0 }}>
<TouchableOpacity activeOpacity={.8}
onPress={() => navigation.navigate('Appointment', { id: item.id, name: item.name, phone: item.phone, email: item.email, session: item.session, player_id: item.player_id, picture: item.picture })} >
<Card style={{ width: width / 2.05, alignItems: 'center', justifyContent: 'center', borderRadius: 15, paddingTop: 10, height: height / 2.4 }}>
<CardItem cardBody>
<Image
source={{ uri: 'http://example.com/storage/' + item.picture }}
style={{ height: 200, width: null, flex: 1 }}
/>
</CardItem>
<CardItem>
<Text> {item.name} </Text>
</CardItem>
</Card>
</TouchableOpacity>
</View>
)
}}
numColumns={2}
/> : <ActivityIndicator size="large" style={{ alignItems: 'center', justifyContent: 'center', flex: 1, flexDirection: 'row' }} />}

First show the profile clicked then swipe between profiles react native

Hi how can I first show the user that I've clicked on and then display a swiper ? I can't find a logic for that. I have a list of users and when I click on one, it should open a new component where we will find more infos about that user. Then I want to swipe between the list of users on the same component of the description ?
Here are my user profile component and the flatlist :
render () {
var colorConnected;
if (this.props.navigation.getParam('Statut') === "ON") {
colorConnected = "#1fbc26";
}
else if (this.props.navigation.getParam('Statut') === "OFF") {
colorConnected = "#ff0303";
}
else {
colorConnected = "#ffd200";
}
return (
<Swiper showsPagination={false}>
{this.state.items.map((item, key) => {
return (
<ScrollView style = {styles.view_container}>
<View style={styles.photo}>
<ImageBackground source={{uri:this.props.navigation.getParam('Photo')}} style={{ width: '100%', height: '100%' }}>
<View style={styles.photo_content}>
<LinearGradient colors={['transparent', 'rgba(0,0,0,0.5)']} style={{ position: 'absolute', left: 0, right: 0, bottom: 0, height: 80 }} />
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
<View>
<Text style={{ fontSize: 40, color:'white' }}>{this.props.navigation.getParam('Age')}</Text>
</View>
<View style={{ marginRight: 7, marginLeft: 7, backgroundColor: '#ffffff', width: 1, height: 39 }}></View>
<View style={{ flexDirection: 'column', flex:1 }}>
<View style={{ flexDirection: 'row' }}>
<View style={[styles.bulle_presence, { backgroundColor: colorConnected } ]}></View>
<Text style={{ fontSize: 18, fontWeight: '600', color:'white' }}>{this.props.navigation.getParam('Pseudo')}</Text>
</View>
<View style={{ flexDirection: 'row', justifyContent: 'space-between'}}>
<Text style={{ fontSize: 15, color:'white' }}>{this.props.navigation.getParam('Distance')}</Text>
<Text style={{ fontSize: 15, color:'white'}}>{this.props.navigation.getParam('Genre')}</Text>
</View>
</View>
</View>
</View>
</ImageBackgroud>
</View>
</ScrollView>
)
})}
</Swiper>
)}
}
render() {
GLOBAL.data = this.state.dataSource;
//console.log(GLOBAL.data);
return (
<SafeAreaView style={{ flex:1 }}>
<View style={styles.main_container}>
<FlatList style={styles.flatList}
data={this.state.dataSource}
extraData = {this.state}
keyExtractor={(item, index) => item.MembreId}
renderItem={(item) => <UserItem user={item} displayDetailForUser={this._displayDetailForUser} />}
numColumns={numColumns}
refreshing={this.state.refreshing}
onRefresh={this.handleRefresh} />
</View>
</SafeAreaView>
)
}
With this code, I'm only able to swipe on the user where I've clicked. The others user are not showing.
You can open a modal then use a carousel like react-native-snap-carousel in full screen mode to generate your use case