How to detect drag end in View React Native - react-native

I have a View. In this view I have a flat list that has the onScrollEndDrag and onScrollBeginDrag logic that works, except when the drag released on the bottom tab menu that is not part of the FlatList.
Because the handler is on the FlatList I can't detect drag releases that happen on the bottom tabs.
I need to have the drag end logic to be attatched to the view instead of the FlatList. How can I detect a when drag ends/the user releases the hand of the screen in the View instead of the FlatList?
Here is what I have currently:
<View>
<StatusBar barStyle={"light-content"} />
<FlatList
data={challenges}
renderItem={({ item, index }) => (
<ChallengePost challenge={item} isVideoPlaying={index === currentlyPlaying && !navigatedOutOfScreen} />
)}
keyExtractor={(challenge) => challenge._id}
showsVerticalScrollIndicator={false}
snapToInterval={Dimensions.get("window").height}
snapToAlignment={"start"}
decelerationRate={"fast"}
onViewableItemsChanged={onViewRef.current}
onScrollEndDrag={() => (scrollEnded.current = true)}
onScrollBeginDrag={() => (scrollEnded.current = false)}
></FlatList>
</View>
as you can see the onScrollEndDrag onScrollBeginDrag happends on the FlatList level and I want it be able to detect drag releases that happen on the entire screen.

Check this library it should help you make it easier because it wraps some of the components in its own pan gesture handlers
react-native-gesture-handler
examples

Related

How to implement a FlatList inside of a Pressable without scrolling getting disabled?

Basically, I want the FlatList to have a onPress functionality (to explain simply) as well as the default scrolling functionality. Right now, if I have a FlatList inside a Pressable, then I am not able to scroll through the FlatList.
I have also tried to put Pressable inside the FlatList's RenderItem component, but I have a lot of items I'll be displaying, so it's going to inefficient.
Instead of Pressable wrapping the FlatList, I learnt that we can use React Native's Gesture Responder System on a simple View to get the behavior that I require.
<View
onStartShouldSetResponder={() => true}
onResponderRelease={doSomethingFunction}
>
<FlatList
data={someData}
renderItem={renderItemComponent}
/>
</View>
Try touch handling on FlatList item parent container like below so the scrolling issue would never come again and you can easily handle the touch on each item separately
<FlatList
style={{...}}
data={[...]}
keyExtractor={(item, index) => index.toString()}
renderItem={({ item }) => (
<TouchableWithoutFeedback onPress={() => {...}}>
<View>
....
</View>
</TouchableWithoutFeedback>
)}
/>

react-native: OnEndReached for Flatlist not working in scrollview

I'm new on ReactNative development and I'm developing my first application.
I'm trying to use OnEndReached in a flat list which is in a scrollview tab. I use this scrollview because I have 3 flat lists in my application.
The first two are horizontal. For the last one, I need to handle the pagination with the onEndReached. But, When I put this last flat list in the scroll view, it doesn't work at all without any issues.
When I put it out of the scrollview, it works correctly. So I assume the issue is related to that.
Do you know how I can manage this issue? I'm sorry if this question is a basic one :(
OnEndReached doesn't call if the parent has ScrollView. Why not put those top views in the Header?
<FlatList
data={data}
renderItem={}
keyExtractor={(item, index) => item.personId}
onEndReached={() => {
console.log(" On End Reached");
}}
onEndReachedThreshold={0.01}
ListHeaderComponent={() => (
<View>
<FlatList/>
<FlatList/>
</View>
))
/>

React Native FlatList OnScrollToTop only fires once

I am creating a project where I need to know when the user scrolls to the top of the flatList
my code is
<FlatList
keyExtractor={item => item.id}
data={this.state.data}
onScrollToTop={console.log('hey')}
renderItem={({ item }) => //blah blah render
/>
terminal only fires hey once
The docs days:
Fires when the scroll view scrolls to top after the status bar has been tapped.
2 things:
It's iOS only
It's when the user tap the status bar (it's more or less a hidden feature)
https://facebook.github.io/react-native/docs/scrollview#onscrolltotop

Needs to tap twice to fire onPress function in ListItem when keyboard is open in react native

Below is my code I am facing issue where when I clicking on list item onPress , it does not work for first time when the keyboard is open so I need to tap twice to order to work it, any help is appreciated.
<FlatList
data={this.state.users}
renderItem={({ item,index }) => (
<ListItem
title={item.userName}
onPress={item => this.sendRequestToTheUser(item)}
containerStyle={{ borderBottomWidth: 0 }} />)}
keyExtractor={(item, index) => index.toString()}
extraData={this.state.userName} />
You should use keyboardShouldPersistTaps=always prop on your FlatList. As RN documentation says:
The keyboard will not dismiss automatically, and the scroll view will not catch taps, but children of the scroll view can catch taps.
So you will be able to tap your buttons just once no matter if keyboard is open.
There's also a medium post that explains how to resolve common keyboard issues on React Native (which also contains Problem 1: Button needs to be tapped twice)

React Native Touchable is disabling ScrollView

I'm new to React Native, so am probably asking something very obvious, but please help.
I have a view wrapped in a touchable, so that the whole area responds to tapping. Then have a ScrollView nested inside the view. The overall structure is something like this:
<TouchableWithoutFeedback onPress={this.handlePress.bind(this)}>
<View>
<ScrollView>
<Text>Hello, here is a very long text that needs scrolling.</Text>
<ScrollView>
</View>
</TouchableWithoutFeedback>
When this compiles and runs, the tapping is detected, but the scroll view doesn't scroll at all. I made the above code short and simple, but each component has the proper styling and I can see everything rendering fine and the long text is cutoff at the bottom of the ScrollView. Please help.
Thank you!
This is what worked for me:
<TouchableWithoutFeedback onPress={...}>
<View>
<ScrollView>
<View onStartShouldSetResponder={() => true}>
// Scrollable content
</View>
</ScrollView>
</View>
</TouchableWithoutFeedback>
The onStartShouldSetResponder prop stops the touch event propagation towards the TouchableWithoutFeedback element.
I'm using this structure it's working for me:
<TouchableWithoutFeedback onPress={() => {}}>
{other content}
<View onStartShouldSetResponder={() => true}>
<ScrollView>
{scrollable content}
</ScrollView>
</View>
</TouchableWithoutFeedback>
You can have a scrollView or FlatList inside a TouchableWithoutFeedback. Tho you shouldn't but some times you have no other choice to go. Taking a good look at this questions and answer validates that.
close react native modal by clicking on overlay,
how to dismiss modal by tapping screen in react native.
For the Question, The only way you can make it work (atleast that i know of), or the simplest way is to add a TouchableOpacity around Text in your code like this,
<TouchableWithoutFeedback onPress={this.handlePress.bind(this)}>
<View>
<ScrollView>
<TouchableOpacity>
<Text>Hello, here is a very long text that needs scrolling.</Text>
</TouchableOpacity>
<ScrollView>
</View>
</TouchableWithoutFeedback>
Note: TouchableOpacity is a wrapper for making Views respond properly to touches so automatically you can style it the way you would have styled your View Component then set some of its special props to whatever you want e.g activeOpacity etc. Moreso you can use TouchableHighlight it works, but it receives one child element i.e you enclose all your component inside a parent one.
I'm using this structure it's working for me:
<TouchableOpacity>
{other content}
<ScrollView>
<TouchableOpacity activeOpacity={1}>
{scrollable content}
</TouchableOpacity>
</ScrollView>
I found that for my situation the other examples did not work as they disabled the ability to click or disabled the ability to scroll. I instead used:
<FlatList
data={[{key: text1 }, { key: text2 } ...]}
renderItem={({ item }) => (
<TouchableWithoutFeedback onPress={this.onPressContent}>
<Text style={styles.text}>{item.key}</Text>
</TouchableWithoutFeedback>
)}
/>
I happend to need to multiple chunks but you could use single element in the data array for one piece of text.
This let the press event to fire as well as let the text scroll.
Trying to use a ScrollView component inside a TouchableWithoutFeedback component can cause some unexpected behavior because the TouchableWithoutFeedback component is designed to capture user gestures and trigger an action, but the ScrollView component is designed to allow users to scroll through content.Here is what the official docs say
Do not use unless you have a very good reason. All elements that
respond to press should have a visual feedback when touched.
TouchableWithoutFeedback supports only one child. If you wish to have
several child components, wrap them in a View. Importantly,
TouchableWithoutFeedback works by cloning its child and applying
responder props to it. It is therefore required that any intermediary
components pass through those props to the underlying React Native
component.
Thats write , you cannot have a scroll view inside the TouchableWithoutFeedback, it the property of react native that it will disable it, you can instead have your scroll view outside the TouchableWithoutFeedback tab and add the other contents that you want upon the click inside a view tag.
You can also use the Touchable Highlights instead, if the TouchableWithoutFeedback does not works.