How to open Picker on TextInput in React Native - react-native

I am learning React Native and I am trying to open Picker on TextInput instead of Keyboard. But, It's not working. Here is my code:
_renderData(item, index) {
{item.fieldName == 'State' ? this._renderPicker() : this._renderTextInput(item, index)}
}
_renderTextInput(item, index){
return (
<TextInput
style={registrationStyles.textInput}
keyboardType={item.keyboardType}
maxLength={item.max}
placeholder={item.placeholder}
onChangeText={text => {this._setValueToJson(text, index, item)}} />
)
}
_renderPicker() {
return (
<Picker
selectedValue={this.state.language}
style={{ height: 50, width: 100 }}
onValueChange={(itemValue, itemIndex) => this.setState({ language: itemValue })}>
{this.props.loginSuccess.result.map((item, index) => {
return (<Picker.Item label={item.state_name} value={index} key={index}/>)
})}
</Picker>
)
}
Here, I am getting a list of Data from API and I am trying to show it in Picker. How is that possible? Thanks in Advance.

Related

React native list map() method add custom element below selected Item

When Item with id=1 selected
then the element appear below
the selected Item. And when
unselected the element disappear.
This is a list with map() method.
The element should be inside the
SrollView like Item
But isn’t a new Item
I have this code that can create a new Item below the selected Item but I don't want to create a new Item but only appear a custom View(element) like above.
Expo Snack> https://snack.expo.dev/#stefanosalexandrou/honest-cashew
You could store the selected index in a state, which you are already doing. Then, use conditional rendering in order to render a custom component below the selected item. Furthermore, if a selected item is pressed again, set the state to undefined.
The handleOnPress function.
function handleOnPress(idx) {
setSelectedId(prev => prev === idx ? undefined : idx)
}
The updated render function.
<View style={styles.container}>
<ScrollView>
<View>
{data.map((person, index) => {
const backgroundColor = index === selectedId ? "#6e3b6e" : "#f9c2ff";
return (
<View>
<TouchableOpacity
onPress={() => handleOnPress(index)}
style={{
padding:20,
backgroundColor: backgroundColor,
marginBottom:20,
}}
>
<Text>{person.name}</Text>
</TouchableOpacity>
{
index === selectedId ? <View style={{backgroundColor: "red", height: 100, width: "100%"}}><Text>Custom Super Component Visible on press of above item </Text></View> : null
}
</View>
);
})}
</View>
</ScrollView>
</View>
I have added a dummy component if the index is selected.
However, you might want to select multiple items one after the other and deselect them individually while having the same effect. For doing so, we change the state to store an array of indices instead.
The updated state and handleOnPress function.
const [selectedIndices, setSelectedIds] = useState([]);
function handleOnPress(idx) {
if (selectedIndices.includes(idx)) {
setSelectedIds(prev => prev.filter(i => i !== idx))
} else {
setSelectedIds(prev => [...prev, idx])
}
}
The updated render function.
return (
<View style={styles.container}>
<ScrollView>
<View>
{data.map((person, index) => {
const backgroundColor = selectedIndices.includes(index) ? "#6e3b6e" : "#f9c2ff";
return (
<View>
<TouchableOpacity
onPress={() => handleOnPress(index)}
style={{
padding:20,
backgroundColor: backgroundColor,
marginBottom:20,
}}
>
<Text>{person.name}</Text>
</TouchableOpacity>
{
selectedIndices.includes(index) ? <View style={{backgroundColor: "red", height: 100, width: "100%"}}><Text>Custom Super Component Visible on press of above item </Text></View> : null
}
</View>
);
})}
</View>
</ScrollView>
</View>
);

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>
);
}

How can I change the numColumns of Flatlist when changing the orientation

I created the function name getOrientation() and put it at useEffect so that whenever I rotate the device, it will rerender the component and show me which orientation the device is.
I also created the variable to determine the orientation by using hook
getOrientation()
const [orientation, setOrientation] = useState("")
const window = useWindowDimensions()
const getOrientation = () => {
if (window.height < window.width) {
setOrientation("LANDSCAPE")
} else {
setOrientation("PORTRAIT")
}
return orientation
}
at useEffect
useEffect(() => {
getOrientation()
})
console.log(orientation)
My problem is that I want to set the numsColumns = 2 in Flatlist (LANDSCAPE) and equals to 1 for the portrait mode but the error popup telling me that I cannot change the numColumns on the fly. What should I do ?
Here is my flatlist
<View style={styles.container}>
<FlatList
contentContainerStyle={{
paddingLeft: insets.left,
paddingRight: insets.right,
}}
data={dishes.dishes}
numColumns={orientation == "LANDSCAPE" ? 2 : 1}
renderItem={({ item, index }) => (
<Tile
style={styles.tileItem}
key={index}
title={item.name}
caption={item.description}
onPress={() => navigation.navigate('Dishdetail_Screen', { dishId: item.id })} // passing infor from one to another screen
// chevron={false}
featured
imageSrc={{
uri: baseUrl + item.image
}}
/>
)}
keyExtractor={item => item.id.toString()} />
</View>
This creepy error
enter image description here
P/s: I'm the fresh React-Native developer. Thanks everyone who is checking my problems
Try adding a key prop to your Flatlist like so with the value being ur orientation:
<FlatList
key={orientation} // add key prop here
contentContainerStyle={{
paddingLeft: insets.left,
paddingRight: insets.right,
}}
data={dishes.dishes}
numColumns={orientation == "LANDSCAPE" ? 2 : 1}
renderItem={({ item, index }) => (
<Tile
style={styles.tileItem}
key={index}
title={item.name}
caption={item.description}
onPress={() => navigation.navigate('Dishdetail_Screen', { dishId: item.id })} // passing infor from one to another screen
// chevron={false}
featured
imageSrc={{
uri: baseUrl + item.image
}}
/>
)}
keyExtractor={item => item.id.toString()} />

FlatList Weird Behavior after appending new data - multiple automatic scrolling

I have a list of data that shows posts feed, whenever user scrolls, the list automatically scrolls multiple times up or down which results in a very bad UX
tried the workaround provided here:
https://stackoverflow.com/questions/43611485/prevent-flatlist-from-scrolling-when-new-items-are-added#=
but it doesn't seem to work for me.
<FlatList
keyboardDismissMode = 'on-drag'
keyboardShouldPersistTaps = 'always'
getItemLayout={(data, index) => (
{length: 575, offset: 575 * index, index}
)}
onScroll = {(event) => {
this.flatListOffset = event.nativeEvent.contentOffset.y
this.setState({
scrollOffset: event.nativeEvent.contentOffset.y
})
}}
contentContainerStyle={{
flexGrow: 1,
width: Dimensions.get('window').width
}}
refreshControl={
<RefreshControl
progressViewOffset={120}
refreshing={this.state.refreshing}
onRefresh={this._onRefresh.bind(this)}
/>
}
ref={(feedView) => (this.feedView = feedView)}
data={this.state.feed}
onEndReached={() => {
if (this.state.hasNextPage && !this.state.loadingMore) {
this.paginateFeed()
}
}}
ListHeaderComponent={this._renderCirclesBar}
ListEmptyComponent={this._renderEmptyState}
ListFooterComponent={() =>
!this.state.loadingMore ? null : (
<ActivityIndicator color="#2962FF" size="large" />
)
}
keyExtractor={this._keyExtractor}
renderItem={this._renderItem}
/>
then at some point:
this.setState({ feed: this.state.feed.concat(....) })
a GIF explaining the issue:
https://gifyu.com/image/9gDD
User PureComponent for rendering and set prop disableVirtualization={true} in flatlist

I am using react-native-swiper-flatlist , but I cannot figure it out how to use scrollToIndex on button press

I am using react-native-swiper-flatlist , I want to scroll forward to some index by tapping button but no clue how to do it. Although I am very beginner to react native development.
I have searched alot but nothing helps, I get an error of undefined is not an object this2.swiper.scrollToIndex'
render() {
return (
<View style={styles.container}>
<SwiperFlatList
ref={swiper => {
this.swiper = swiper;
}}
data={[
{ key: "a" },
{ key: "b" },
{ key: "c" },
{ key: "d" },
{ key: "e" }
]}
index={0}
renderItem={({ item, index }) => (
<View>
<Image
style={styles.child}
source={require("../../assets/advertisementtwo.png")}
/>
<Image
style={styles.child}
source={require("../../assets/advertisementtwo.png")}
/>
<Image
style={styles.child}
source={require("../../assets/advertisementtwo.png")}
/>
<Image
style={styles.child}
source={require("../../assets/advertisementtwo.png")}
/>
<Button
title={"Next"}
onPress={this.swiper.scrollToIndex(1, true)}
style={{ backgroundColor: "white" }}
/>
</View>
)}
/>
</View>
);
}
Should swipe on button click
Here is the screenshot of the error I am getting
Try adding ref='swiper' as a SwiperFlatList prop,
Example
<SwiperFlatList ref='swiper'/>
this.refs.swiper._scrollToIndex(2)
For those who are using React hook instead of class, you can do sth like that to utilise the scrollToIndex function
//First, make a ref for storing the swiper instance inside your swiper compoent
const swiperRef = useRef<any>({});
//Second, store the reference
<SwiperFlatList
ref={(component) => { swiperRef.current._swiper = component; }}
>
//Later on, you can call the function like this
swiperRef.current._swiper.scrollToIndex({index: 2})