Flatlist scroll position onScroll - react-native

I am building a header that animates/hides as the user scrolls down a Flatlist.
Is there any way to find out the scroll position of the Flatlist in pixels?
I'm using react native 0.59.8.
I've tried using onScroll hoping it passes a value to the callback - it doesn't.
I've also tried onScrollBeginDrag, onScrollEndDrag and onMomentumScrollEnd.. None of them provide information of the current scroll position.
onSroll={(info)=>{console.log(info)}
I would expect to get some information about the scroll, but none is passed.

use the code
<FlatList onScroll={this.handleScrollView} />
handleScrollView: function(event: Object) {
this.setState({ scrollPosition: event.nativeEvent.contentOffset.y });
}

its working
onScroll={(r) => console.log(r.nativeEvent.contentOffset.y)}
post your code here if you want to find bug

A Flatlist, as said in the docs, has all the props of a ScrollView, so as answered here,
Add a handler to your FlatList:
<FlatList onScroll={this.handleScroll} />
And then:
handleScroll: function(event) {
console.log(event.nativeEvent.contentOffset.y);
},

Related

How can I prevent vertical scrolling of parent Flatlist when scrolling horizontally in child view?

I have a Flatlist with Vertical Scrolling and inside each item of the Flatlist I have a SwipeListView from react-native-swipe-list-view.
Whenever I Swipe horizontally inside the SwipeListView, it gets cancelled if i also start scrolling vertically and then it starts vertically scrolling the Flatlist. I tried using useState to manage the scrollEnabled but this only works when the User slowly slides inside the SwipeListView. With increased velocity there are messed up animations. Also i feel like there must be a cleaner way of achieving this. Anyone know a way to basically disable FlatList scroll while scrolling inside of child component?
For starters, replace react-native-swipe-list-view with the swipable component that react native gesture handler exports. This is far more performant as it uses the UI thread to perform all animations. You can then import Flatlist as well from react-native-gesture-handler.
Generally, things should work as is. But if there is any glitchy behaviour you can wrap flatlist with a gestureHandlerRootView and pass RNGH ScrollView to the flatlist renderScrollComponent.
import Swipeable from 'react-native-gesture-handler/Swipeable';
import {Flatlist} from 'react-native-gesture-handler'
import {
GestureHandlerRootView,
PanGestureHandler,
ScrollView,
} from 'react-native-gesture-handler';
export default function App(){
<GestureHandlerRootView>
<Flatlist renderItem={<Swipeable />}
renderScrollComponent={ScrollView}/>
</GestureHandlerRootView>
}
You can try implementing the swipeableRow which can be used to disable scrolling in flatlist.
disableScroll() {
this.list.getScrollResponder().setNativeProps({
scrollEnabled: false
})
}
enableScroll() {
this.list.getScrollResponder().setNativeProps({
scrollEnabled: true
})
}
Then in your place of your swipeable component, add this:
<SwipeableRow onSwipeStart={disableScroll} onSwipeEnd={enableScroll} />
Also you can try adding this to the FlatList
scrollEnabled={false}

FlatList not working inside BottomSheet on Android

I am using gorhom/react-native-bottom-sheet
The issue I am facing:
I have a FlatList inside a BottomSheet, I am able to scroll in FlaLlist on ios but it is not working on android.
After a lot of research, I was able to resolve the issue by using BottomSheetFlatList instead of FlatList from the same package.
import { BottomSheetFlatList } from "#gorhom/bottom-sheet";
<BottomSheetFlatList
ref={ref}
initialNumToRender={3}
keyExtractor={(item) => item?.id}
showsVerticalScrollIndicator={false}
maxToRenderPerBatch={3}
windowSize={7}
data={dat}
renderItem={renderItem}
/>
By doing so, it started working fine on android too.
But as I also wanted my Flatlist to auto-scroll using ref on a particular event.
After some research and because of the great documentation of #gorhom/bottom-sheet. I found out the solution in the troubleshooting section of the docs.
But as a developer, StackOverflow is our first go-to place for every issue. So, I decided to post the answer here.
ANSWER
Due to wrapping the content and handle with TapGestureHandler & PanGestureHandler, any gesture interaction would not function as expected.
To resolve this issue, please use ScrollView & FlatList from react-native-gesture-handler provide instead react-native.
import {
ScrollView,
FlatList
} from 'react-native-gesture-handler';
find the original answer here-
https://gorhom.github.io/react-native-bottom-sheet/troubleshooting
Using raw-bottom-sheet raw-bottom-sheet and set "dragFromTopOnly" as true, and any touch operation can be performed i will mention
example below:
<RBSheet
ref={refRBSheet}
dragFromTopOnly={true}
customStyles={{
wrapper: {
backgroundColor: "transparent"
},
draggableIcon: {
backgroundColor: "#000"
}
}}
>`

Adding longpress event in react native

I have one input box, through which I am adding some text, on longpress I have to make the added fields as editable, how can I do that in react native.
If you want to make your filed clickable without seeing a buton then you should use touchableopacity.
Try this;
<TouchableOpacity onLongPress={this._onLongPress}>
<Input/>
</TouchableOpacity>
_onLongPress = () => {
this.setState({
makeEditableFunction: true
})
}

ScrollToIndex does not scroll the FlatList as expected

I have a FlatList setup like so
<FlatList
style={styles.listContainer}
data={this._formatList()}
renderItem={this.renderItem}
keyExtractor={this.keyExtractor}
ItemSeparatorComponent={this.renderSeparator}
nestedScrollEnabled
showsVerticalScrollIndicator={false}
extraData={this.state}
ref={this._setRef}
/>
I also have these following two relevant functions in my component
_setRef = (ref) => {
this._listref = ref;
}
_scrollToTop = () => {
this._listref.scrollToIndex({ index: 0, animated: true });
}
I have checked that the this._listref is setup correctly when FlatList is rendered.
The function _scrollToTop is called from a button click (and it is indeed called).
For some reason the list does not scroll to top as expected.
I have tried various options playing with viewOffset / viewPosition.
It seems no scrolling action is taking place.
This is an expo project with "sdkVersion": "33.0.0"
and React and RN as follows from package.json
"react": "16.8.3",
"react-native": "https://github.com/expo/react-native/archive/sdk-33.0.0.tar.gz",
Thanks.
From the docs: https://facebook.github.io/react-native/docs/flatlist#scrolltoindex
Note: Cannot scroll to locations outside the render window without
specifying the getItemLayout prop.
So you'll need to implement getItemLayout for scrolling to the top to work properly with scrollToIndex since most certainly it will be outside of the current render window.
You could alternatively use scrollToOffset: https://facebook.github.io/react-native/docs/flatlist#scrolltooffset with a param of {offset: 0} instead.
Have you tried using offset?
this.listRef.getNode().scrollToOffset({ offset: 0, animated: true });
OR
this.listRef.scrollToOffset({ animated: true, offset: 0 });
Trying using this and I hope this will work assuming that you've correctly set up the reference of the scrollview and passing that correctly in the function.

How to set fixed position the react native action button on the screen

Can I set the position of react native action button to fixed on a flat list?
I have added an action button but when I scroll the flat list, the action button hides!
Thanks, advance.
You'll want to use the Animated API
First you need to create a Flatlist that you can animate. This is easily done with Animated.createAnimatedComponent():
import { Flatlist, Animated } from 'react-native'
const AnimatedFlatlist = Animated.createAnimatedComponent(Flatlist)
Now in your parent component constructor create a new Animated.Value. This will be the value you use to animate your component to scroll along with your AnimatedFlatlist:
constructor(props) {
super(props)
this.state = { translateY: new Animated.Value(0)}
}
Then wrap the component you want to be fixed in an Animated.View and make sure you add a transform to the component style, passing it the animated value you created :
<Animated.View style={{ transform: [{ translateY: this.state.translateY }]}}>
{YourFixedComponent}
</Animated.View>
Finally, you need to attach an Animated.event to your AnimatedFlatlist. This is done using the onScroll prop:
<AnimatedFlatlist
data={...}
renderItem={...}
keyExtractor={...}
onScroll={Animated.event(
[{nativeEvent: {contentOffset: {y: this.state.translateY}}}],
{useNativeDriver: true}
)}
scrollEventThrottle={1}
/>
Now your element with move along with your Flatlist. This is a basic example, and you will probably need to mess with interpolation and CSS positioning to get it exactly as you want it.