How to control swapping on click of button in carousel in react-native? - react-native

When I will click on button I want to control my swapping slides of carousel .That means if I will click on button then new slide will come in carousel.
I am using 'react-native-snap-carousel' package for achieve my functionality in react-native.so please help me how I can achieve this functionality.Thank you in advance.
SwapSlide = (value) => {
this.setState({ indexvalue: value }, () => {
console.log("get swapindex ===>>>", this.state.indexvalue)
})
}
onPressAnswer = (item) => {
console.log("run increase method===>>>", this.increase('progress', 10));
console.log("run swapslide method===>>>", this.SwapSlide.snapToNext());
this.AddQuestionAnswer(item)
}
renderItemAnswer = ({ item, index }) => {
return (
<View>
<TouchableOpacity style={styles.answerTouchable} onPress={() =>this.onPressAnswer(item)}>
<Text style={styles.answerText}>{item.answer}</Text>
</TouchableOpacity>
</View>
)
}
<Carousel
data={questionList}
renderItem={this.renderItemQuestion}
hasParallaxImages={true}
itemWidth={wp('100%')}
sliderWidth={wp('100%')}
ref={(value)=>{this.SwapSlide=value}}
/>
<TouchableOpacity onPress={() => { this.setState({ indexvalue: indexvalue + 1 }) }}><Text style={styles.skiptext}>Skip</Text></TouchableOpacity>

Use method snapToNext() for next slide
<TouchableOpacity onPress={() => this.SwapSlide.snapToNext()}><Text style={styles.skiptext}>Skip</Text></TouchableOpacity>
For Previous slide you can use this.SwapSlide.snapToPrev()

Related

how do i get a value picked from another screen?

im using navigation to pass between screens.
now,im trying to figure out how can i get a value from second screen to the first screen ?
the user needs to pick a color value from the second screen and return selcted color to the first screen.
this is the code im using .
enter code here
<CustomButton
style={styles.buttonPicker}
darkMode={this.props.darkMode}
title={'pick a color'}
onPress={() => {
this.props.navigation.navigate('ColorPickerScreen', {
onSubmit: (namecolor) => {
console.log('55555555555555', { getNameColor })
},
})
}}
></CustomButton>
enter code here
onSelect = (color) => this.props.navigation.navigate('CreatenewtTipul')
render() {
return (
<Image
style={styles.img}
source={require('../components/icons/color-wheel.png')}
/>
<ColorPicker
colors={this.state.colors}
selectedColor={this.state.selectedColor}
onSelect={this.onSelect}
/>
<Text>Selected Color = {this.state.selectedColor}</Text>
</View>
)
}
}
tnx for any help
arik :)
To pass value from screen A to screen B:
navigation.navigate('ScreenB', {
itemId: 86,
otherParam: 'anything you want here',
});
To access that value in Screen A:
const { itemId, otherParam } = route.params;
Where were route here is part of the screen's props, check the guide here for more info
im not trying to pass a value to the second screen.
im trying to get a value from the second screen to the first screen.
You can pass a function as a callback from the first screen to the second screen in params on call that on your second screen.
function Screen1(props) {
const onSelect = (selectedColor) => {
console.log('selectedColor', selectedColor)
}
const navigateToSecondScreen = () => {
props.navigation.navigate('Screen2', {
onColorSelect: onSelect
})
}
return(
<View>
<TouchableOpacity onPress={navigateToSecondScreen}>
<Text>Go to second screen</Text>
</TouchableOpacity>
</View>
)
}
//Second Screen
function Screen2(props) {
const {onColorSelect} = props.route.params;
return(
<View>
<TouchableOpacity onPress={() => {onColorSelect('color value')}}>
<Text>your other code here</Text>
</TouchableOpacity>
</View>
)
}
The idea is just to call the function which you have passed as a param from Screen1

Double tap on a Flatlist React Native

I'm trying to recreate Instagram's double tap on an item and a heart appears for a few seconds. Im currently rendering text items in a flatist (1 item per page) and I want the user to be able to double tap the text section and a heart will appear.
I can't seem to get both the flatList and the animation to work together. Any ideas? In my current code it will only render the flatList and not the Animated.image. I tried wrapping the animated image in an oppress in a touchable without feedback, still no luck
const onDoubleTap = useCallback(() => {
//console.log("tapped");
scale.value = withSpring(1, undefined, (isFinished) => {
if (isFinished) {
scale.value = withDelay(500, withSpring(0));
console.log("Double Tapped");
}
});
}, []);
return (
<TapGestureHandler
numberOfTaps={2}
onActivated={onDoubleTap}
>
<Animated.View>
<FlatList
horizontal={false}
decelerationRate={"fast"}
snapToAlignment={"center"}
snapToInterval={Dimensions.get("screen").height}
data={flatl}
// keyExtractor={(item, index) => `id_${index}`}
style={styles.fullScreen}
renderItem={({ item }) => (
<View style={[{ ...styles.fullHeight }]}>
<Text>{item.name}</Text>
</View>
)}
/>
<AnimatedImage
source={require("../assets/heart.png")}
style={[
styles.image,
rStyle,
]}
resizeMode={"center"}
/>
</Animated.View>
</TapGestureHandler>
);
}

Calling modal on a list of products opens the modal for all of them instead of just the one being clciked

I am making a react native app that loads data from google firebase and then display it on a page, when a user clicks on any of the products aa modal will open to show more datails.
I am using useEffect to load the data on page load then display then results:
const fetchData = async () => {
const categories = db.collection("productsDB");
const collections = await categories
.limit(6)
.onSnapshot((querySnapshot) => {
const items = [];
querySnapshot.forEach((documentSnapshot) => {
items.push({
...documentSnapshot.data(),
key: documentSnapshot.id,
});
});
setItems(items);
setLoading(false);
});
return () => collections();
};
useEffect(() => {
fetchData();
}, []);
and the show them like this:
{loading ? (
<ActivityIndicator />
) : (
items.map((item) => (
<TouchableOpacity
style={styles.queryResult}
key={item.key}
onPress={() => {
setModalVisible(!modalVisible);
}}
>
<View style={styles.queryResultContent}>
<Image
style={{ width: 100, height: 100 }}
source={{ uri: String(item.images) }}
/>
<View>
<Text style={styles.queryInfoHeader}>{item.name}</Text>
</View>
</View>
<View>
<ProductModal
isModalVisible={modalVisible}
setModalVisible={setModalVisible}
navigation={navigation}
{...item}
/>
</View>
</TouchableOpacity>
))
)}
when I open the modal, it opens the modal for all of the products and doesnt really matter if I click on the first product or what, it opens all of the modals, and I am not sure how to get rid of this!
is there any better way to write this function?
You're using the same modalVisible flag for all of your modals; therefore, they either are all visible or all hidden.
Why not have a single modal rather than rendering a bunch of them in the loop, and pass the item as a prop to it?

(React Native) Change color to a text after onPress() it

I have a drawer with some text elements created dynamically.
I would like to select an item from the drawer, "show selected item" (like change the color of the text of that item) and re-change it to default when another one item is selected.
The text that I'd like to "change onPress" is inside the <TouchableWithoutFeedback> tag (i'm rendering some HTML code with react-native-render-html)
<FlatList
ItemSeparatorComponent={this.FlatListItemSeparator}
data={this.state.data}
renderItem={({ item }) => (
//on touch --> open article (call _onTextPress)
<TouchableWithoutFeedback onPress={this.navigateToScreen('Category', {id: item.id, title: item.name})}>
<View style={styles.categories}>
<HTML html={'<p style="color:#fd3a18; font-size:20px;"><strong>'+item.name+'</strong></p>\n'}/>
</View>
</TouchableWithoutFeedback>
)}
keyExtractor={({ id }, index) => id.toString()}
/>
navigateToScreen(routeName, params) {
return () => {
this.props.navigation.dispatch(NavigationActions.navigate({ routeName, params }))
this.props.navigation.closeDrawer();
};
}
If I understood correctly you want to change the color of selected item
//Add Selected Item to the State
state = {selectedItemId:'myId'}
// Change The State Whenever Selected
navigateToScreen(routeName, params) {
this.setState({selectedItemId:params.id})
return () => {
this.props.navigation.dispatch(NavigationActions.navigate({ routeName, params }))
this.props.navigation.closeDrawer();
};
}
Now Change the color conditionally.
<FlatList
ItemSeparatorComponent={this.FlatListItemSeparator}
data={this.state.data}
renderItem={({ item }) => (
//on touch --> open article (call _onTextPress)
<TouchableWithoutFeedback onPress={this.navigateToScreen('Category', {id: item.id, title: item.name})}>
<View style={styles.categories}>
<HTML html={`<p style="color:${this.state.selectedItemId == item.id ? "red" : "#fd3a18"}; font-size:20px;"><strong>'+item.name+'</strong></p>\n`}/>
</View>
</TouchableWithoutFeedback>
)}
keyExtractor={({ id }, index) => id.toString()}
/>

FlatList not rendering style dynamically

I'm currently struggling in making my FlatList applying the changes I do to it. What I am wanting right now is that when I click an item in my flatlist, that it highlights in a certain color. I followed an approach done by a guy but I am having the problem that to me is not working the update once I click.
I can see through console that all I am doing performs a modification but I think that I am missing some point with extraData parameter since it is not re-rendering with the backgroundColor that I would like to apply.
The code I have is as following, I know that the style I am applying is correct since if i substitute in the map styles.list per styles.selected, everything gets the background I would like to be applied to the elements I click.
So summarizing, the issue I think I have is that the flatlist is not re-rendering so it doesn't show the modifications I perform on it. Any idea of what I am doing wrong? Any tip?
render() {
const { students, studentsDataSource, loading, userProfile } = this.props.navigation.state.params.store;
this.state.dataSource = studentsDataSource._dataBlob.s1.map(item => {
item.isSelect = false;
item.selectedClass = styles.list;
return item;
})
const itemNumber = this.state.dataSource.filter(item => item.isSelect).length;
return (
<View style={styles.container}>
<Item rounded style={styles.searchBar}>
<Input placeholder='Group Name'/>
</Item>
<FlatList
style={{
flex: 1,
width: "100%",
}}
data={this.state.dataSource}
ItemSeparatorComponent={this.FlatListItemSeparator}
renderItem={ ({ item }) => (
<ListItem avatar style={[styles.list, item.selectedClass]}
onPress={() => this.selectItem(item)}>
<Left>
{!item.voteCount && <Avatar unseen={true} /> }
{!!item.voteCount > 0 && <Avatar />}
</Left>
<Body>
<Text>{item.name}</Text>
<Text note>{item.group}</Text>
</Body>
</ListItem>
)
}
listKey={item => item.key}
extraData={this.state}
/>
</View>
);
}
Here we can find the state and SelectItem functions:
constructor(props) {
super(props)
this.state = {
dataSource : [],
}
}
//FlatListItemSeparator = () => <View style={styles.line} />;
selectItem = data => {
//{console.log("inside SelectItem=", data)}
data.isSelect = !data.isSelect;
data.selectedClass = data.isSelect? styles.selected: styles.list;
const index = this.state.dataSource.findIndex( item => data.key === item.key);
this.state.dataSource[index] = data;
this.setState({
dataSource: this.state.dataSource,
});
console.log("This state has the changes:=",this.state.dataSource)
};
Well the main issue was that I was not using the .setState and instead I was doing assignations which killed the listeners.