react-native-draggable-flatlist
react-native-draggable-flatlist copied to clipboard
Using DraggableFlatList causes PagerView to be unable to swipe between pages
Using DraggableFlatList causes PagerView to be unable to swipe between pages
https://github.com/user-attachments/assets/d1c08e82-e595-4c17-a13a-aa8bb0ef5a86
MyPageView.tsx ` import React from 'react'; import { View, Text, StyleSheet, TouchableOpacity, Animated, Dimensions } from 'react-native'; import Layout from '../Layout'; import AIDRIVEN from './driven'; import Finance from './finance'; import CENTER from './centre'; import PagerView from 'react-native-pager-view'; import { useImmer } from 'use-immer';
const { width } = Dimensions.get('window'); // 获取屏幕宽度
const HomeScreen = () => { return ( <> <Layout /> <MyTab /> </> ); };
function MyTab() { const [currentPage, setCurrentPage] = React.useState(0); const [pageData, setPageData] = useImmer({ pageActive: [false, false, false], }); const translateX = React.useRef(new Animated.Value(0)).current; const pagerRef = React.useRef<PagerView>(null);
const handlePageChange = (event: any) => { const newPosition = event.nativeEvent.position; setCurrentPage(newPosition); setPageData((draft) => { draft.pageActive[newPosition] = true; }); };
const handlePageScroll = (event: any) => { const { offset, position } = event.nativeEvent; translateX.setValue(position * (width / 3) + offset * (width / 3)); };
const goToPage = (pageIndex: number) => { setCurrentPage(pageIndex); setPageData((draft) => { draft.pageActive[pageIndex] = true; }); pagerRef.current?.setPage(pageIndex); };
return ( <> <View style={styles.navBar}> {['AI-DRIVEN', 'FINANCE', 'CENTER'].map((title, index) => ( <TouchableOpacity key={index} onPress={() => goToPage(index)} style={styles.navItem} > <Text style={styles.navText}>{title}</Text> </TouchableOpacity> ))} <Animated.View style={[ styles.indicator, { transform: [{ translateX }] }, ]} /> </View> <PagerView ref={pagerRef} style={{ flex: 1 }} initialPage={currentPage} onPageSelected={handlePageChange} onPageScroll={handlePageScroll} > <View key="0"> <AIDRIVEN isActive={pageData.pageActive[0]} /> </View> <View key="1"> <Finance isActive={pageData.pageActive[1]} /> </View> <View key="2"> <CENTER isActive={pageData.pageActive[2]} /> </View> </PagerView> </> ); }
const styles = StyleSheet.create({ navBar: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', paddingVertical: 10, backgroundColor: '#f8f8f8', }, navItem: { alignItems: 'center', flex: 1, height: 25, }, navText: { fontSize: 16, }, indicator: { position: 'absolute', bottom: 0, height: 3, width: width / 3, backgroundColor: 'blue', left: 0, }, });
export default HomeScreen; `
Finance.tsx ` import React, {useState, useMemo} from 'react'; import {Text, StyleSheet, TouchableOpacity} from 'react-native'; import DraggableFlatList, { ScaleDecorator, RenderItemParams, } from 'react-native-draggable-flatlist';
// 将索引映射到数据
const mapIndexToData = (index: number) => {
return {
text: ${index}
,
key: key-${index}
,
};
};
export type Item = ReturnType<typeof mapIndexToData>;
const NUM_ITEMS = 10;
export default React.memo(({isActive}: {isActive: boolean}) => { // 使用 useMemo 缓存初始数据 const initialData = useMemo(() => { return Array.from({length: NUM_ITEMS}, (_, index) => mapIndexToData(index), ); }, []);
const [data, setData] = useState<Item[]>(initialData);
const renderItem = ({item, drag, isActive}: RenderItemParams<Item>) => { // 根据 isActive 状态确定背景颜色 const backgroundColor = isActive ? 'red' : 'white';
return (
<ScaleDecorator>
<TouchableOpacity
activeOpacity={1}
onLongPress={drag}
disabled={isActive}
style={[styles.rowItem, {backgroundColor}]}>
<Text style={styles.text}>{item.text}</Text>
</TouchableOpacity>
</ScaleDecorator>
);
};
return ( <DraggableFlatList data={data} keyboardShouldPersistTaps="always" nestedScrollEnabled={true} onDragEnd={({data: newData}) => { // 使用 map 创建新数据以避免直接修改原始数据 const updatedData = newData.map((item, index) => ({ ...item, backgroundColor: getColor(index, NUM_ITEMS), // 重新计算背景颜色 })); setData(updatedData); // 更新状态 }} keyExtractor={item => item.key} renderItem={renderItem} /> ); });
const styles = StyleSheet.create({ rowItem: { height: 100, alignItems: 'center', justifyContent: 'center', borderWidth: 1, marginTop: 10, marginBottom: 10, width: '90%', marginHorizontal: '5%', }, text: { fontSize: 24, fontWeight: 'bold', textAlign: 'center', }, });
`