React Native Flatlist Example - reactjs

HOW CAN I HANDLE MUCH DATA IN REACT NATIVE FLATLIST?
Is there anyone who can offer an example using React Native Flatlist's ScrollToIndex?
I am working with ScrollToIndex and getItemLayout but it's not working.
There are 185 items on my flatlist and when I have called ScrollToIndex(150), there's no result.
I have worked with Google for getting ScrollToIndex Example but there's nothing.
Thanks for your help.
Here's my code:
<FlatList
ref={ref => setFlatListRef(ref)}
// getItemLayout={getItemLayout}
data={markers}
keyExtractor={(item, index) => index}
ItemSeparatorComponent={() => <Separator color={colors.separator} />}
renderItem={renderItem}
style={{ flex: 1 }}
getItemLayout={getItemLayout}
/>
const getItemLayout = (data, index) => {
return {
length: 120,
offset: 120 * index,
index
}
}
const renderItem = ({ item }) => <MyListItem {...props} item={item} />
class MyListItem extends React.PureComponent {
render () {
console.log('purecom')
let cost = null
if (this.props.item.minCost != -1 && this.props.item.maxCost != -1) {
const entities = new Entities()
if (this.props.item.minCost == 0 && this.props.item.maxCost == 0) {
cost = 'Guide price: Free'
} else if (
this.props.item.minCost == this.props.item.maxCost &&
this.props.countries[this.props.item.countryID] &&
this.props.countries[this.props.item.countryID].currencySymbol
) {
cost =
`Guide price: ` +
entities.decode(
this.props.countries[this.props.item.countryID].currencySymbol
) +
`${this.props.item.minCost.toFixed(2)}`
} else {
if (
this.props.countries[this.props.item.countryID] &&
this.props.countries[this.props.item.countryID].currencySymbol
) {
cost =
`Guide price from` +
entities.decode(
this.props.countries[this.props.item.countryID].currencySymbol
) +
`${this.props.item.minCost.toFixed(2)} to` +
entities.decode(
this.props.countries[this.props.item.countryID].currencySymbol
) +
`${this.props.item.maxCost.toFixed(2)}`
}
}
}
return (
<TouchableOpacity
style={{
padding: 5,
height: 120,
backgroundColor:
this.props.selectedMarkerID !== this.props.item.ID.toString()
? '#fff'
: colors.separator
}}
activeOpacity={1}
onPress={() => this.props.selectItem(this.props.item)}
>
<Text style={{ fontWeight: 'bold', fontSize: 13 }}>
{this.props.item.Name}
</Text>
<Text style={{ marginTop: 1, fontSize: 12 }}>
{this.props.item.desc}
</Text>
<Text style={{ marginTop: 1, fontSize: 12 }}>
{this.props.markerTypes ? (
this.props.markerTypes[this.props.item.Type].ShortDescription
) : (
''
)}
</Text>
<View style={{ flexDirection: 'row', marginTop: 5 }}>
<View style={{ marginRight: 2 }}>
<MyCustomMarker
source={{ url: markerTypesImages[this.props.item.Type] }}
style={{ width: 25, height: 30 }}
userFavourites={this.props.userFavourites}
Type={this.props.item.Type}
markerID={this.props.item.ID}
/>
<Image
source={{ url: images.compass }}
style={{
marginTop: 2,
width: 20,
height: 20,
marginLeft: 5,
transform: [
{ rotate: `${this.props.item.rotate.toString()}deg` }
]
}}
/>
<Text style={{ fontSize: 9 }}>{this.props.item.distance}km</Text>
</View>
{this.props.item.thumb === '' ? (
<Image
source={{ url: images.noThumb }}
style={{ flex: 0.2, width: 84, height: 65 }}
/>
) : (
<Image
source={{
url: `${this.props.url}${this.props.item.thumb}`
}}
style={{ flex: 0.2, width: 80, height: 60 }}
/>
)}
<View style={{ flex: 0.5 }}>
<View style={{ flexDirection: 'row', flexWrap: 'wrap' }}>
{Object.keys(facilities).map((key, i) => {
if (this.props.item[key] === 1) {
return (
<View
style={{
width: 26,
height: 26,
padding: 2,
margin: 2,
alignItems: 'center',
borderRadius: 3,
borderWidth: 1,
borderColor: colors.dark,
backgroundColor: 'white'
}}
key={key}
>
<Image
source={{ url: facilities[key] }}
style={{ width: 20, height: 20 }}
/>
</View>
)
}
return null
})}
</View>
<StarRatingBar
continuous={true}
score={this.props.item.score / 2}
allowsHalfStars={true}
accurateHalfStars={true}
dontShowScore={true}
/>
<View>
{cost ? <Text style={{ fontSize: 12 }}>{cost}</Text> : null}
{this.props.item.open ? (
<Text style={{ color: this.props.item.style, fontSize: 12 }}>
{this.props.item.open}
</Text>
) : null}
</View>
</View>
</View>
</TouchableOpacity>
)
}
}
setFlatListRef(flatListRef) {
this.setState({ flatListRef })
}
if (index >= 0) {
this.setState({ selectedIndex: index })
setTimeout(() => {
this.state.flatListRef.scrollToIndex({
index,
viewPosition: 0.5
})
}, 100)
}

Related

React Native Custom Drawer Navigation (navigation.closeDrawer())

I'm new to react native i've been trying to create a custom drawer. Inside i wanted to add a button that would close the drawer however i've been getting the error TypeError: undefined is not an object (evaluating 'navigation.closeDrawer') this is my code:
import React, { useState } from "react";
import {DrawerActions} from '#react-navigation/native';
import Logo from '../assets/images/Logo.png'
import {
View,
Text,
Image,
TouchableOpacity,
ScrollView
} from 'react-native';
import {
createDrawerNavigator,
DrawerContentScrollView,
} from '#react-navigation/drawer';
import { MainLayout } from "../screens";
import {
COLORS,
FONTS,
SIZES,
constants,
icons,
dummyData,
} from '../constants';
import Animated from "react-native-reanimated";
const Drawer = createDrawerNavigator()
const CustomDrawerItem = ({label, icon}) => {
return (
<TouchableOpacity
style={{
flexDirection: 'row',
height: 40,
marginBottom: SIZES.base,
alignItems: 'center',
paddingLeft: SIZES.radius,
borderRadius: SIZES.base
}}
>
<Image
source={icon}
style={{
width: 20,
height: 20,
tintColor: COLORS.primary
}}/>
<Text
style={{
marginLeft: 15,
color: COLORS.primary,
...FONTS.h3
}}
>
{label}
</Text>
</TouchableOpacity>
)
}
const CustomDrawerContent = ({ navigation }) => {
return (
<DrawerContentScrollView
scrollEnbled={true}
contentContainerStyle={{ flex: 1}}
>
<ScrollView
style={{
flex: 1,
paddingHorizontal: SIZES.radius
}}
>
{/* Logo*/}
<TouchableOpacity
style = {{
flexDirection: 'row',
marginTop: SIZES.radius,
alignItems: 'center',
marginBottom: 20,
}}>
<Image style={{
flex: 1,
width: 80,
height: 80,
resizeMode: 'contain',
marginLeft: -60,
}}
source={Logo}/>
<View
style={{
marginLeft: SIZES.radius
}}
>
<View
style={{
alignItems: 'flex-end',
justifyContent: 'center'
}}
>
<TouchableOpacity
style={{
alignItems: 'center',
justifyContent: 'center',
tintColor: COLORS.black
}}
onPress={() => navigation.closeDrawer()}
>
<Image
source={icons.cross}
style={{
height: 25,
width: 25,
}}
/>
</TouchableOpacity>
</View>
</View>
</TouchableOpacity>
{/* Profile */}
<TouchableOpacity
style = {{
flexDirection: 'row',
marginTop: SIZES.radius,
alignItems: 'center'
}}>
<View
style={{
marginLeft: SIZES.radius
}}
>
<CustomDrawerItem
icon={icons.profile}
label={constants.sideBarElements.guest}
/>
<View>
{dummyData.GuestData.map(
(item, index) => (
<Text
style={{
paddingLeft: 20,
paddingTop: 10,
color: COLORS.gray
}}>
{item.name}
</Text>
)
)}
</View>
</View>
</TouchableOpacity>
{/* Line devider
<View
style={{
height: 1,
marginVertical: SIZES.radius,
//marginLeft: SIZES.radius,
backgroundColor: COLORS.lightGray1
}}
/>*/}
{/* Drawer Items */}
<View
style={{
flex: 1,
marginTop: SIZES.padding,
marginLeft: SIZES.radius
}}
>
<CustomDrawerItem
icon={icons.cart}
label={constants.sideBarElements.store}
/>
<View>
{dummyData.storesData.map(
(item, index) => (
<Text
style={{
paddingLeft: 20,
paddingTop: 10,
color: COLORS.gray
}}>
{item.title}
</Text>
)
)}
</View>
</View>
<View
style={{
flex: 1,
marginTop: SIZES.padding,
marginLeft: SIZES.radius,
marginBottom: 50
}}
>
<CustomDrawerItem
icon={icons.cart}
label={constants.sideBarElements.categories}
/>
<View>
{dummyData.carouselData.map(
(item, index) => (
<Text
style={{
paddingLeft: 20,
paddingTop: 10,
color: COLORS.gray
}}>
{item.category}
</Text>
)
)}
</View>
</View>
</ScrollView>
</DrawerContentScrollView>
)
}
const CustomDrawer = () => {
const [progress, setProgress] = useState(new Animated.Value(0))
const scale = Animated.interpolateNode(progress, {
inputRange: [0, 1],
outputRange: [1, 0.8]
})
const borderRadius = Animated.interpolateNode(progress, {
inputRange: [0, 1],
outputRange: [0, 26]
})
const animatedStyles = {borderRadius, transform: [{scale}]}
return (
<View
style={{
flex: 1,
backgroundColor: COLORS.primary
}}
>
<Drawer.Navigator
drawerType='slide'
overlayColor='transparent'
drawerStyle={{
flex: 1,
width: '65%',
paddingRight: 20,
backgroundColor: 'transparent'
}}
sceneContainerStyle={{
backgroundColor: 'transparent'
}}
initialRouteName='MainLayout'
drawerContent={props => {
setTimeout(()=> {
setProgress(props.progress)
}, 0)
return (
<CustomDrawerContent
navigration ={props.navigation}
/>
)
}}
>
<Drawer.Screen name='MainLayout'>
{props => <MainLayout {...props} drawerAnimationStyle={animatedStyles}/>}
</Drawer.Screen>
</Drawer.Navigator>
</View>
)
}
export default CustomDrawer;
i even tried it with dispatch but i get the same error i'm not sure what i'm doing wrong.
Try this
import {useNavigation} from '#react-navigation/native';
const navigation = useNavigation();
navigation.openDrawer();
navigation.closeDrawer();

can't write on my textInput inside my flatlist

I try to do a profil update with a flatlist to catch all my value and attribute. but when i want to write something new is not working. i tried to take off my placeholder and my default value with my actual value, then write something but i have the same problem.
const Item = ({ attribute, value, item }) => {
return (
<View
key={item}
style={{
flex: 1,
flexDirection: "column",
marginBottom: 20,
paddingLeft: 10,
}}>
<View
style={{
flexDirection: "row",
flex: 1,
alignItems: "center",
marginBottom: 5,
}}>
<View style={{ marginRight: 10 }}>
<Feather
onPress={() => {
setOnEdit(true);
}}
name="edit"
size={24}
color="#8E8E8E"
/>
</View>
<Text style={{ color: "#FF6B35", fontWeight: "bold" }}>
{attribute}
</Text>
</View>
<View style={{ flex: 1 }}>
<View style={{ flex: 1 }}>
{onEdite ? (
<TextInput
defaultValue={value}
placeholder={value}
placeholderTextColor={"black"}
onChangeText={(text) => {
createHandler(text, attribute);
}}
/>
) : (
<Text style={{ color: "#8E8E8E" }}>{value}</Text>
)}
</View>
</View>
</View>
)
);
};
this is also my createHandler method of all my textInput
const createHandler = (text, fieldName) => {
console.log(text, fieldName);
setForm((oldValue) => {
return {
...oldValue,
[fieldName]: text,
};
});
};

Flat List renderItem width issue

I have some flat lists in my app with an item width of 160. For some reason when I reduce the width to 130 it will work as planned but with a width of 160px it starts to rerender again and again. What will be the possible reason for this and how to fix the issue.
My code
<FlatList
horizontal
inverted={getFlatListOrientation()}
data={data}
keyExtractor={(item, index) => index.toString()}
renderItem={({ item, index }) => renderItem(item, index)}
contentContainerStyle={styles.listContainerStyle}
showsHorizontalScrollIndicator={false}
/>
this is my render item component
<TouchableWithoutFeedback
onPress={() => {
this.onSelect();
}}
>
<View style={{ height: 168,
width: 130,
marginRight: 10,
backgroundColor: kBackgroundWhiteColor,
shadowColor: kSeparatorTintColor,
shadowOffset: { width: 1, height: 1 },
shadowOpacity: 0.5,
shadowRadius: 5,
borderRadius: 5,
elevation: 10,}>
<FastImage
style={styles.imageStyle}
resizeMode={FastImage.resizeMode.cover}
source={
loadingError
? PLACE_HOLDER_IMAGE
: {
uri: photoUrl,
priority: FastImage.priority.normal,
}
}
onLoad={() => {
this.setState({ loadingImage: false });
}}
onError={() => {
this.setState({ loadingError: true });
}}
>
<View
style={{
flexDirection: "row",
flexGrow: 1,
justifyContent: "space-between",
alignItems: "center",
transform: [
{
rotateY: isKSA() ? "180deg" : "0deg",
},
],
}}
>
<TouchableOpacity
style={{
right: 0,
bottom: 0,
position: "absolute",
}}
onPress={() => this.onAddCarTofavorites()}
>
<View style={{ paddingLeft: 8, paddingTop: 8 }}>
<View
style={{
width: 26,
height: 26,
alignItems: "center",
justifyContent: "center",
borderRadius: 13,
backgroundColor: "#00000033",
marginRight: 5,
marginBottom: 5,
}}
>
<Image
source={
isFavorited
? IC_HEART_FILLED
: IC_HEART_OUTLINE
}
style={styles.favoriteImageStyle}
backgroundColor="clear"
/>
</View>
</View>
</TouchableOpacity>
{seenCarsIdlist &&
seenCarsIdlist.indexOf(id + "") != -1 && (
<Seen />
)}
{cappasity_link && <Tag3D />}
</View>
</FastImage>
{loadingImage && (
<FastImage
style={{
...styles.mainImageStyle,
position: "absolute",
}}
resizeMode={FastImage.resizeMode.cover}
source={PLACE_HOLDER_IMAGE}
/>
)}
<View style={styles.innerContainerStyle}>
<Text
style={styles.titleTextStyle}
ellipsizeMode={"tail"}
numberOfLines={1}
>
{makeName && modelName
? `${makeName} ${modelName} ${trim}`
: `${title} ${trim}`}
</Text>
<Text style={styles.priceTextStyle}>
{price + translate("filter_label_sar")}
</Text>
<View style={{ flexDirection: "row", paddingTop: 10 }}>
<Text style={styles.yearMileageTextStyle}>
{`${year} ยท ${mileage} ${
mileageUnitTemp
? mileageUnitTemp
: mileageUnit
}`}
</Text>
</View>
</View>
</View>
</TouchableWithoutFeedback>

how can I animate show item inside a card in react native

I want the card to expand and shrink with duration
const renderNote = (item) => {
if (item.id === noteId) {
if (item.note) {
return (
<View>
<Title style={{ alignSelf: "center", paddingVertical: 10, color: colors.primary,fontSize:17 }}>Your Note</Title>
<Text style={{ paddingLeft: 10 ,backgroundColor:colors.background,paddingVertical:10,borderRadius:5}}>{item.note}</Text>
</View>
);
}
return (
<View>
<Title style={{ alignSelf: "center", paddingVertical: 10, color: colors.primary ,fontSize:17}}>Your Note</Title>
<Text style={{ paddingLeft: 10 ,backgroundColor:colors.background,paddingVertical:10,borderRadius:5}}>There is no note</Text>
</View>
);
}
};
return (
<View style={{ marginTop: 20 }}>
<Title style={{ alignSelf: "center" }}>{AppointmentTitle}</Title>
<ScrollView style={{ minHeight: 100 }}>
{Appointment.slice(0, 2).map((item) => {
return (
<View key={item.id}>
{item ? (
<TouchableWithoutFeedback
onPress={() => {
noteId === item.id ?
setNoteId(null):
setNoteId(item.id)
}}
>
<Card style={[{ margin: 10, borderRadius: 10 }, styles.shadow]}>
<Card.Content>
<Text style={{ fontSize: 16 }}>
You have an appontment with <Text style={{ color: colors.primary }}>{item.patinetName}</Text>
</Text>
{isTime ? renderFutureTime(item.dateTime) : renderTime(item.dateTime)}
{renderNote(item)}
when renderNote the card expand how to animation on this code
........................................................................................................

how to update state according to id in react native?

I have a flatist as follows:
const displayMessageList = (message) => {
return (
<View>
{message.length > 0 && enableMoreMessages ? (
<View style={{ justifyContent: "center", alignItems: "center" }}>
<TouchableOpacity onPress={() => fetchMoreMessages()}>
<Text>More</Text>
</TouchableOpacity>
</View>
) : null}
<FlatList data={message} renderItem={displayMessageRenderItem} />
</View>
);
};
where displaymessagerenderitem is as follows:
const displayMessageRenderItem = ({ item }) => {
var audio;
return (
<View style={{ padding: 10 }}>
{item.type == 2 ? (
<View>
{item.media_list && item.media_list.length > 0 && (
<View style={styles.servermessage}>
{item.media_list[0].media_url ? (
<Image
source={{ uri: item.media_list[0].media_url }}
style={{ height: 300, width: 300 }}
resizeMode="contain"
/>
) : null}
</View>
)}
<View style={styles.servermessage}>
<Text style={styles.servertext}>{item.message}</Text>
<Text style={styles.server_time_to_display}>
{item.time_to_display}
</Text>
</View>
</View>
) : (
<View style={{ alignItems: "flex-end" }}>
{item.media_list && item.media_list.length > 0 && (
<View style={styles.sendermessage}>
{item.type_of_message_content === "image" ? (
item.media_list[0].media_url ? (
<Image
source={{ uri: item.media_list[0].media_url }}
style={{ height: 300, width: 300 }}
resizeMode="contain"
/>
) : null
) : item.media_list[0].media_url ? (
soundpause === true ? (
<>
<View
style={{
flexDirection: "row",
justifyContent: "center",
alignItems: "center",
}}
>
{item.sender && item.sender.pic_url != "" && (
<Image
source={{ uri: item.sender.pic_url }}
style={{ height: 50, width: 50, borderRadius: 25 }}
resizeMode="contain"
/>
)}
<TouchableOpacity
onPress={() =>
listenaudio(item.media_list[0].media_url, item.id)
}
>
<AntDesignIcon
name="caretright"
size={25}
color="#E23744"
/>
</TouchableOpacity>
<Image
source={Images.seekline}
style={{ height: 3 }}
tintColor="#E23744"
/>
</View>
</>
) : (
<>
<View
style={{
flexDirection: "row",
justifyContent: "center",
alignItems: "center",
}}
>
{item.sender && item.sender.pic_url != "" && (
<Image
source={{ uri: item.sender.pic_url }}
style={{ height: 50, width: 50, borderRadius: 25 }}
resizeMode="contain"
/>
)}
<TouchableOpacity
onPress={() =>
listenaudio(item.media_list[0].media_url)
}
>
<AntDesignIcon
name="caretright"
size={25}
color="#B2B2B2"
/>
</TouchableOpacity>
<Image source={Images.seekline} style={{ height: 3 }} />
</View>
{/* <Text>{item.media_list[0].media_url}</Text> */}
</>
)
) : null}
<Text style={styles.sender_time_to_display}>
{item.time_to_display}
</Text>
</View>
)}
{item.message != "" && (
<View style={styles.sendermessage}>
<Text style={styles.sendertext}>{item.message}</Text>
<Text style={styles.sender_time_to_display}>
{item.time_to_display}
</Text>
</View>
)}
</View>
)}
</View>
);
};
inside listenaudio() I want to set the state of pause to true/false but only for the selected item :
const listenaudio = (audio, id) => {
setsoundpause(!soundpause);
console.log('audio', audio)
var sound = new Sound(audio, Sound.MAIN_BUNDLE, (error) => {
if (error) {
console.log('failed to load the sound', error);
return;
}
// loaded successfully
console.log('duration in seconds: ' + sound.getDuration() + 'number of channels: ' + sound.getNumberOfChannels());
// Play the sound with an onEnd callback
sound.play((success) => {
if (success) {
console.log('successfully finished playing');
} else {
console.log('playback failed due to audio decoding errors');
}
});
});
console.log('listen to', sound);
sound.setVolume(1);
};
However when I select the item all state for all the items in the list are changing, could anyone please help me out here?
Any leads would be great.
Let me know if anything else is required.
Thanks in advance
You can manage playing sound with id
const [playingId,setPlayingId] = useState(0)
set id in listenaudio function
setPlayingId(id);
and comapre in displayMessageRenderItem
playingId == item.id

Resources