How to scroll FlatList component to some index/children after dragging the FlatList?
For Example:
As we can see in Youtube/TikTok stories, when we drag the screen the next video appears immidiatly after it. So, I am implementing it with FlatList, if we drag the item below then FlatList should move to the above item/index. So, what I am doing is that storing the currently displayed index and on onScrollEndDrag prop I am checking the position of Y, and accordingly run scrollToIndex function, but it's not working.
Reason
Because while scrolling after drag, FlatList ignores the scrollToIndex function.
Is their anyone to help me out of it???
import React from 'react';
import { View, Text, StyleSheet, AppState, FlatList, Animated, Dimensions } from 'react-native';
import fetchDataFromDirectory from '../data/fetchDataFromWhatsApp';
import PlayerVideo from '../components/VideoPlayer';
import Image from '../components/Image';
const { width, height } = Dimensions.get('window');
const AnimatedFlatList = Animated.createAnimatedComponent(FlatList);
class VideoScreen extends React.Component {
state = {
pdfInfo: [], //[{id, name, path},...]
appState: '',
viewableIndex: 0
}
fetchData = async () => {
const data = await fetchDataFromDirectory('videos');
this.setState({ pdfInfo: data.pdfInfo });
}
componentDidUpdate(prevProps, prevState) {
if (this.state.pdfInfo.length > this.dataLength) { //We are seeing if we need to scroll to top or not
this.dataLength = this.state.pdfInfo.length;
try {
this.list.scrollToIndex({ animated: true, index: 0, viewPosition: 0 })
} catch (err) {
}
}
}
handleAppStateChange = (nextAppState) => {
//the app from background to front
if (this.state.appState.match(/inactive|background/) && nextAppState === 'active') {
this.fetchData();
}
//save the appState
this.setState({ appState: nextAppState });
}
componentDidMount() {
this.videoHeight = height;
this.dataLength = 0;
this.fetchData();
AppState.addEventListener('change', this.handleAppStateChange);
}
onViewableItemsChanged = ({ viewableItems, changed }) => {
// console.log("Visible items are", viewableItems);
// console.log("Changed in this iteration", changed);
try {
this.setState({ viewableIndex: viewableItems[0]['index'] })
} catch (err) {
}
}
componentWillUnmount() {
AppState.removeEventListener('change', this.handleAppStateChange)
}
render() {
return <AnimatedFlatList
onLayout={(e) => {
const { height } = e.nativeEvent.layout;
this.videoHeight = height;
}}
// onResponderRelease={e => {console.log(e.nativeEvent.pageY)}}
// onResponderRelease={(e) => console.log(e.nativeEvent.)}
// onScrollBeginDrag
// snapToAlignment={'top'}
// onMoveShouldSetResponderCapture={(e) => {e.nativeEvent.}}
// decelerationRate={'fast'}
decelerationRate={'fast'}
scrollEventThrottle={16}
// onScroll={(e) => console.log('+++++++++++++++++',Object.keys(e), e.nativeEvent)}
onScrollEndDrag={(e) => {
// this.list.setNativeProps({ scrollEnabled: false })
console.log(e.nativeEvent)
if (e.nativeEvent.velocity.y > 0.1) {
console.log('go to above')
this.list.scrollToIndex({animated: true, index: this.state.viewableIndex - 1, viewPosition: 0})
} else if (e.nativeEvent.velocity.y < -0.9){
console.log('go to below')
this.list.scrollToIndex({animated: true, index: this.state.viewableIndex + 1, viewPosition: 0})
}
// if (e.nativeEvent.velocity.y < 0.1000 && e.nativeEvent.velocity.y >= 0) {
// this.list.scrollToIndex({animated: true, index: this.state.viewableIndex, viewPosition: 0})
// }
// else if (e.nativeEvent.velocity.y < -0.1000 && e.nativeEvent.velocity.y < 0) {
// this.list.scrollToIndex({animated: true, index: this.state.viewableIndex, viewPosition: 0})
// }
// this.list.setNativeProps({ scrollEnabled: true })
console.log('h1')
}}
viewabilityConfig={{
// itemVisiblePercentThreshold: 90,
viewAreaCoveragePercentThreshold: 60
}}
// extraData={this.state.viewableIndex}
onViewableItemsChanged={this.onViewableItemsChanged}
// scr
contentContainerStyle={styles.screen}
data={this.state.pdfInfo}
keyExtractor={item => item.id}
ref={ref => this.list = ref}
renderItem={({ item, index }) => {
// console.log(index)
return <PlayerVideo
source={item.path}
refList={this.list}
height={this.videoHeight}
index={index}
isViewable={this.state.viewableIndex == index ? true : false} />
}}
</View>
}}
/>
}
}
export default VideoScreen;
const styles = StyleSheet.create({
screen: {
backgroundColor: '#111212',
// flex: 1
}
})