Rendering Favourites icon to Flat list - react-native

Any ideas to render favourites button the one with a heart shape on Flatlists in React Native? This I have here works fine, I get the data from a REST api correctly without worries, but the primary challenge is , having to have the favourites button to it.
Flat List code looks like this
render() {
return (
<View style={styles.MainContainer}>
<FlatList
data={ this.state.dataSource }
ItemSeparatorComponent = {this.FlatListItemSeparator}
renderItem={({item}) =>
<View style={{flex:1, flexDirection: 'row'}}>
<Image source = {{ uri: item.url_image}} style={styles.imageView} />
<Text onPress={this.GetItem.bind(this, item.movie_description)} style={styles.textView} >{item.movie_description}</Text>
</View>
}
keyExtractor={(item, index) => index.toString()}
/>
</View>
);
}
}
Help would be very much appreciated!

At the main View in renderItem
<View style={{flex:1, flexDirection: 'row'}}>
<Image source = {{ uri: item.url_image}} style={styles.imageView} />
<Text onPress={this.GetItem.bind(this, item.movie_description)} style={styles.textView} >{item.movie_description}</Text>
</View>
you can simply add png image or any favourite icon, but you have to give it position: 'absolute' if you want favourite icon to be float on the card, you can add image into main View in the renderItem like this
<Image
source={your png or jpg file's path}
style={{
height: 25,
width: 25,
position: 'absolute',
top: 15,
right: 15
}}/>

Related

Styling Two Elements on Same Line in React Native

I am trying to style two elements that need to appear on the same line in my react native app. What I have thus far positions them on the same line - using nested <Text> elements - but I'm unclear how to then be able to create some distance between them. For instance, in the example below, I want the icon to be left-aligned, which it is now, but I want the this.props.client.name text to be center-aligned. From my understanding margin is ignored in children elements. How can I accomplish this?
<View>
<Text>
<Feather name="chevron-left" size={24}
onPress={() => props.navigation.goBack()}
/>
<Text>{this.props.client.name}</Text>
</Text>
</ View>
You can try styling them using "flex" css properties.
for example if you have:
<View>
<Text>
<Feather name="chevron-left" size={24}
onPress={() => props.navigation.goBack()}
/>
<Text>{this.props.client.name}</Text>
</Text>
</ View>
TRY
<View>
<Text>
<View style={{ display: "flex", alignItems: "center",
position: "relative", zIndex: 1 }}>
<Feather name="chevron-left" size={24}
onPress={() => props.navigation.goBack()}
style={{position: "absolute", zIndex: 2, left: 0 }}
/>
<Text>{this.props.client.name}</Text>
</View>
</Text>
</ View>
You should now have your Icon on the left and your text centered.
Read more about Flexbox here. reactnative.dev/docs/flexbox

React native navigate like click post in Instagram

I am making an album app with react native and want to make FlatList with images like Instagram. When clicks item of FlatList, it will navigate to the same item in another screen with different FlatList. How to do this?
when click image JS
navigate to it in another screen
My code:
const RenderItemList = ({item, index}) => {
return (
<Pressable onPress={() => navigation.navigate('detail')}>
<View key={index} style={[index%3!==0 ? {paddingLeft:2} : {paddingLeft:0}, {marginBottom: 2}]}>
<Image style={{width: sizeOfImage, height: sizeOfImage}}
source={{uri : item.uri}}
/>
</View>
</Pressable>
)}
You can use initialScrollIndex prop from the Flatlist API. Pass the index as route params to other screen and set initialScrollIndex to that index.
Example below
<FlatList
data={sampleImages}
keyExtractor={(item) => item.id.toString()}
numColumns={3}
renderItem={({ item, index }) => (
<Pressable
style={{ width: EachWidth, height: EachWidth }}
onPress={() => navigation.navigate('Details', { initialScroll: index })}>
<Image
source={{ uri: item.download_url }}
style={{ width: EachWidth, height: EachWidth }}
/>
</Pressable>
)}
/>
On other screen,
<FlatList
data={sampleImages}
keyExtractor={(item) => item.id.toString()}
initialScrollIndex={route.params.initialScroll || 0} // Use here
renderItem={({ item }) => (
<View style={{ width: ScreenWidth, height: ScreenWidth }}>
<Image
source={{ uri: item.download_url }}
style={{ width: ScreenWidth, height: ScreenWidth }}
/>
</View>
)}
/>
Working Example

Horizontal Flatlist Re-Render changes ListHeaderComponent

I'm banging my head on this one. I am using a horizontal flat list. And putting a view in ListHeaderComponent to act as padding. You can see it as a blue box in the first image below. That works great. Trouble is, when I refresh the flatlist from elsewhere in my app, the padding seems to break. See the blue box in image 2 below. Code below images. Any help appreciated.
OnLoad:
After props refresh:
<FlatList
ref={(ref) => { this.flatListRef = ref; }}
horizontal={true}
showsHorizontalScrollIndicator={false}
data={this.props.store.allBookData}
ListHeaderComponent={<View style={{ width: itemOffset / 2, height: 200, backgroundColor: 'blue' }}></View>}
ListFooterComponent={<View style={{ width: itemOffset /2 }}></View>}
renderItem={({ item }) =>(
<TouchableWithoutFeedback onPress={() => this.gotoBook(item)}>
<Animatable.View
animation={"fadeIn"}
easing={"ease-in-out"}
duration={320}
delay={240}
useNativeDriver={true}
style={[styles.bookItem, { width: itemWidth, height: itemHeight, marginTop: itemMarginTop, opacity: 1, marginRight: 24 }]}>
{/* cover */}
<View style={[styles.bookCover, { width: itemWidth, height: bookHeight, backgroundColor: global.setBookItemColor(item.color)}]}>
<View style={styles.bookBindingHolder}>
<View style={styles.bookBinding}></View>
</View>
<View style={styles.bookCoverPhotoHolder}>
<View style={styles.bookCoverPhoto}>
<FastImage style={styles.bookCoverFrame} resizeMode={'contain'} source={Images.coverFrameWithTape}/>
{(() => {
//display cover
if (item.cover == 'temp') {
//temp
return (<FastImage style={styles.bookCoverImg} resizeMode={'cover'} source={Images.tempCover} />)
}else{
//photo
return (
<FastImage
style={[styles.bookCoverImg, {opacity: 0.88}]}
resizeMode={'cover'}
source={{uri: item.cover}}>
</FastImage>
)
}
})()}
</View>
</View>
</View>
{/* title */}
<View style={styles.bookTitleHolder}>
<Text style={[global.TextStyles.h3, global.TextStyles.darkText, global.TextStyles.alignCenter]}>{item.title}</Text>
</View>
{/* count */}
<View style={styles.bookPhotoCountHolder}>
<View style={styles.bookPhotoCount}>
{(() => {
if (item.photoCount == global.maxPhotos){
var itemCount = 'Full'
}else{
var itemCount = item.photoCount + '/' + global.maxPhotos
}
return(
<Text style={[global.TextStyles.lightText, global.TextStyles.smallerLabel]}>{itemCount}</Text>
)
})()}
</View>
</View>
</Animatable.View>
</TouchableWithoutFeedback>
)}/>
It's hard to say where the problem comes from even though there's a good chance it comes from your itemOffset that you apply as width to your HeaderComponent.
However, I have the impression that you can make it easier to define paddings, instead of defining a header and footer component, you could simply apply paddings to the content of your list by passing to your list the props: contentContainerStyle
like that
<FlastList
...
contentContainerStyle={{
paddingHorizontal: itemOffset / 2
}}
/>
but I think you should look in your calcul of itemOffset

How to scroll FlatList in Modal component?

My Horizontal FlatList doesn't scroll in Modals. You can find my FlatList and RenderItem codes below:
<FlatList
data={this.props.selectedGroupData.groupMembersList}
renderItem={this.ilgiliKisiler}
keyExtractor={item => item.uid}
nestedScrollEnabled={true}
horizontal={true}
removeClippedSubviews={true}
/>
</View>
and renderItem function:
ilgiliKisiler = ({ item }) => {
console.log("on Related Users item => ", item);
return (
<TouchableOpacity style={{flex: 1}}>
<View style={{ flexDirection: "row" }}>
<View style={styles.relatedUsersContainer}>
<View style={{ alignItems: "center" }}>
<Image
source={
item.avatar
? { uri: item.avatar }
: require("../../assets/images/defaultAvatar.png")
}
style={styles.relatedUsersImage}
/>
</View>
<View style={{ flexDirection: "column" }}>
<Text style={styles.relatedUsersText} numberOfLines={2}>
{item.name}
</Text>
</View>
</View>
</View>
</TouchableOpacity>
);
};
Before this post, i found some solutions like style={{flex: 1}}. When i try to this solutions, my renderItem doesn't appear.
Use propagateSwipe props for smooth scrolling in <Modal>
<Modal propagateSwipe>...</Modal>
for more detail react-native-modal issue #236
Sorry for posting this as an answer, but I can't comment because of my low reputation. I'll remove this answer if it doesn't work for you.
Have you tried using contentContainerStyle on your FlatList like so:
contentContainerStyle={{ flexGrow: 1 }}
You can read more about contentContainerStyle at this link: https://facebook.github.io/react-native/docs/scrollview#contentcontainerstyle
Wrap the Flatlist inside a scrollview. It should work.
<Scrollview>
<Flatlist />
</Scrollview>

react-native nested ScrollView fails to respond to touch in android

I'm building a 'Search' component, in which a ScrollView is displayed when the search terms in the TextInput return related tags from the API endpoint. While running in iOS the component works as expected and allows me to scroll through the list and select an option. However, android does not seem to allow scroll or touch events on the ScrollView component. I've decorated the component with the keyboardShouldPersistTaps="always" and nestedScrollEnabled={true}.
Attempted placing the ScrollView at different levels of the overall screen. When close to the top level View, the ScrollView works as intended, but at a certain depth, it ceases to work. Having the ScrollView higher up in the component would require a lot of calculation based on the onLayout events of each nested View in order for the component to match designs, so I'd like to avoid it if possible.
<ScrollView
style={Style.view}
contentContainerStyle={Style.container}
keyboardShouldPersistTaps="handled"
>
<TouchableOpacity
onPress={this.onClose}
style={Style.close}
hitSlop={{
top: 16,
right: 16,
bottom: 16,
left: 16,
}}
>
<Icon
name="times"
size={24}
color={Palette.$color_white}
/>
</TouchableOpacity>
<Animated.View style={[Style.animatedWrapper, { transform: [{ translateY }] }]}>
<View style={Style.tags}>
{
tags.map(tag => (
<View key={tag.guid} style={Style.tag}>
<Strong color={Palette.$color_white}>{tag.name}</Strong>
<TouchableOpacity
style={Style.tagButton}
onPress={() => this.onTagPress(tag)}
hitSlop={{
top: 16,
right: 16,
bottom: 16,
left: 16,
}}
>
<Icon name="times" size={14} color={Palette.$color_white} />
</TouchableOpacity>
</View>
))
}
</View>
<View style={Style.searchWrapper} onLayout={this.onLayout}>
<Image
source={Buzz}
style={Style.illustration}
/>
<View style={Style.inputWrapper}>
<Heading
level={3}
color={Palette.$color_white}
>
Search by key words
</Heading>
<View style={Style.controlWrapper}>
<View style={{ flex: 1 }}>
<TextInput
ref={(ref) => { this.input = ref; }}
returnKeyType="done"
textContentTypez="none"
placeholder="Type your search"
onChangeText={this.onChangeText}
onFocus={this.onFocus}
onBlur={this.onBlur}
underlineColorAndroid="transparent"
placeholderTextColor={Palette.$color_white}
style={Style.searchInput}
/>
<Animated.View
style={[Style.menu, { opacity: menuOpacity }]}
pointerEvents={isMenuOpen ? 'auto' : 'none'}
>
<ScrollView
contentContainerStyle={Style.menuOptionsContentContainer}
keyboardShouldPersistTaps="always"
style={[Style.menuOptions, { maxHeight: scrollHeight }]}
nestedScrollEnabled
>
{
!isLoading
? results.map(tag => (
<TouchableHighlight
style={Style.menuOption}
key={tag.guid}
onPress={() => this.onOptionSelect(tag)}
underlayColor={Palette.$color_light_grey}
>
<Text style={Style.menuOptionText}>{tag.name}</Text>
</TouchableHighlight>
))
: (
<View style={Style.activityIndicator}>
<ActivityIndicator size="small" color={Palette.$color_orange} />
</View>
)
}
</ScrollView>
</Animated.View>
</View>
<StyledTextButton
title="Search"
onPress={this.onSearchPress}
disabled={tags.length <= 0}
/>
</View>
</View>
</View>
</Animated.View>
</ScrollView>
The ScrollView is rendered as expected, but in android it cannot respond to touch and swipe gestures. Works as intended in iOS.
Here's an example in iOS of the Component.