Skip to content

Commit 360d050

Browse files
authored
docs: 添加react-native-draggable-flatlist的example (#5)
Signed-off-by: 李琦 <liqi219@h-partners.com>
1 parent 1e4699a commit 360d050

File tree

8 files changed

+645
-0
lines changed

8 files changed

+645
-0
lines changed

Example/App.tsx

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
// import './shims'
2+
3+
import React from 'react';
4+
import "react-native-gesture-handler";
5+
import { Platform, UIManager } from 'react-native'
6+
import { NavigationContainer } from '@react-navigation/native';
7+
import { SafeAreaProvider } from 'react-native-safe-area-context';
8+
import { GestureHandlerRootView } from 'react-native-gesture-handler';
9+
import { createStackNavigator } from '@react-navigation/stack';
10+
import Swipeable from "./screens/Swipeable";
11+
import Basic from "./screens/Basic";
12+
import Nested from "./screens/Nested";
13+
import Horizontal from "./screens/Horizontal";
14+
15+
16+
if (Platform.OS === 'android') {
17+
UIManager.setLayoutAnimationEnabledExperimental &&
18+
UIManager.setLayoutAnimationEnabledExperimental(true);
19+
}
20+
21+
import { View, Text, Button } from 'react-native';
22+
23+
const Stack = createStackNavigator();
24+
25+
class Home extends React.Component {
26+
onPress1 = () => {
27+
this.props.navigation.navigate('Basic');
28+
}
29+
onPress2 = () => {
30+
this.props.navigation.navigate('Swipeable');
31+
}
32+
onPress3 = () => {
33+
this.props.navigation.navigate('Nested');
34+
}
35+
onPress4 = () => {
36+
this.props.navigation.navigate('Horizontal');
37+
}
38+
39+
render() {
40+
return (
41+
<View style={{padding:14}}>
42+
<View style={{height:50}}>
43+
<Button title="Basic" onPress={this.onPress1}></Button>
44+
</View>
45+
<View style={{height:50,marginTop:12}}>
46+
<Button title="Swipeable" onPress={this.onPress2}></Button>
47+
</View>
48+
<View style={{height:50,marginTop:12}}>
49+
<Button title="Nested" onPress={this.onPress3}></Button>
50+
</View>
51+
<View style={{height:50,marginTop:12}}>
52+
<Button title="Horizontal" onPress={this.onPress4}></Button>
53+
</View>
54+
55+
</View>
56+
);
57+
}
58+
};
59+
60+
class App extends React.Component {
61+
render() {
62+
return (
63+
<GestureHandlerRootView style={{ flex: 1, backgroundColor: 'seashell' }}>
64+
<SafeAreaProvider>
65+
<NavigationContainer>
66+
<Stack.Navigator initialRouteName="draggleList">
67+
<Stack.Screen name="draggleList" component={Home} />
68+
<Stack.Screen name="Basic" component={Basic} />
69+
<Stack.Screen name="Swipeable" component={Swipeable} />
70+
<Stack.Screen name="Nested" component={Nested} />
71+
<Stack.Screen name="Horizontal" component={Horizontal} />
72+
</Stack.Navigator>
73+
</NavigationContainer>
74+
</SafeAreaProvider>
75+
</GestureHandlerRootView>
76+
);
77+
}
78+
}
79+
80+
81+
// export default App;
82+
83+
export default {
84+
displayName: 'react-native-draggable-flatlist',
85+
framework: 'React',
86+
category: 'UI',
87+
title: 'react-native-draggable-flatlist',
88+
documentationURL: 'react-native-draggable-flatlist',
89+
description: '',
90+
examples: [
91+
{
92+
title: 'react-native-draggable-flatlist',
93+
render: function (): any {
94+
return <App />;
95+
},
96+
},
97+
],
98+
};

Example/screens/Basic.tsx

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import React, { useState, useRef } from "react";
2+
import { Text, StyleSheet, View } from "react-native";
3+
import DraggableFlatList, {
4+
ScaleDecorator,
5+
RenderItemParams,
6+
} from "react-native-draggable-flatlist";
7+
import { Gesture, GestureDetector } from "react-native-gesture-handler";
8+
import { runOnJS } from "react-native-reanimated";
9+
import { mapIndexToData, Item } from "../utils";
10+
11+
const NUM_ITEMS = 10;
12+
const initialData: Item[] = [...Array(NUM_ITEMS)].map(mapIndexToData);
13+
14+
export default function Basic() {
15+
const [data, setData] = useState(initialData);
16+
const draggableListRef = useRef(null);
17+
18+
const renderItem = ({ item, drag, isActive, getPanGestureRef }: RenderItemParams<Item> & { getPanGestureRef?: () => any }) => {
19+
const panRef = getPanGestureRef?.();
20+
const longPress = Gesture.LongPress()
21+
.simultaneousWithExternalGesture(panRef || [])
22+
.onStart(() => {
23+
console.log("LongPress.onStart", {
24+
key: item.key,
25+
});
26+
runOnJS(drag)();
27+
})
28+
.onEnd((_e, success) => {
29+
console.log("LongPress.onEnd", { success });
30+
});
31+
32+
return (
33+
<ScaleDecorator>
34+
<GestureDetector gesture={longPress}>
35+
<View
36+
style={[
37+
styles.rowItem,
38+
{ backgroundColor: isActive ? "red" : item.backgroundColor },
39+
]}
40+
>
41+
<Text style={styles.text}>{item.text}</Text>
42+
</View>
43+
</GestureDetector>
44+
</ScaleDecorator>
45+
);
46+
};
47+
const renderPlaceholderFunction = ({ item, index }: { item: Item; index: number }) => {
48+
return (
49+
<View style={[
50+
{ backgroundColor: `${item.backgroundColor}30` } // 30% 透明度
51+
]}>
52+
<Text>拖动 "{item.text}"</Text>
53+
</View>
54+
);
55+
};
56+
return (
57+
<DraggableFlatList
58+
data = {data}
59+
ref = {draggableListRef}
60+
onDragBegin = {(index) => {
61+
console.log("onDragBegin", { index });
62+
}}
63+
onPlaceholderIndexChange ={(index) => {
64+
console.log("onPlaceholderIndexChange", { index });
65+
}}
66+
onDragEnd = {({ data, from, to }) => {
67+
console.log("onDragEnd", { from, to });
68+
setData(data);
69+
}}
70+
keyExtractor = {(item) => item.key}
71+
renderItem = {renderItem}
72+
onScrollOffsetChange = {(offset) => {
73+
console.log('onScrollOffsetChange:', offset);
74+
}}
75+
onRelease = {(index) => {
76+
console.log('onRelease:', index);
77+
}}
78+
containerStyle = {styles.listContainer}
79+
activationDistance = {20}
80+
animationConfig = {{
81+
damping: 10,
82+
mass: 0.5,
83+
stiffness: 300,
84+
overshootClamping: false,
85+
}}
86+
debug = {false}
87+
dragHitSlop = {{ top: -10, left: -10, bottom: -10, right: -10 }}
88+
renderPlaceholder = {renderPlaceholderFunction}
89+
autoscrollThreshold = {200}
90+
autoscrollSpeed = {200}
91+
/>
92+
93+
);
94+
}
95+
96+
const styles = StyleSheet.create({
97+
listContainer: {
98+
flex: 1,
99+
backgroundColor: "#bcaaaaff",
100+
},
101+
rowItem: {
102+
height: 100,
103+
alignItems: "center",
104+
justifyContent: "center",
105+
},
106+
text: {
107+
color: "white",
108+
fontSize: 24,
109+
fontWeight: "bold",
110+
textAlign: "center",
111+
},
112+
});

Example/screens/Home.tsx

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import React from 'react';
2+
import { Text, TouchableOpacity, View } from 'react-native';
3+
import { useNavigation } from '@react-navigation/native';
4+
5+
function Home() {
6+
return (
7+
<View style={{ flex: 1, backgroundColor: 'seashell' }}>
8+
<Link to="Basic" />
9+
<Link to="Swipeable" />
10+
<Link to="Nested" />
11+
<Link to="Horizontal" />
12+
</View>
13+
);
14+
}
15+
16+
export default Home;
17+
18+
function Link({ to }: { to: string }) {
19+
const navigation = useNavigation();
20+
21+
return (
22+
<TouchableOpacity
23+
onPress={() => navigation.navigate(to)}
24+
style={{
25+
padding: 14,
26+
}}>
27+
<Text style={{ color: '#555', fontSize: 24, fontWeight: 'bold' }}>
28+
{to}
29+
</Text>
30+
</TouchableOpacity>
31+
);
32+
}

Example/screens/Horizontal.tsx

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import React, { useCallback, useState } from "react";
2+
import { Text, View, StyleSheet, TouchableOpacity } from "react-native";
3+
import { Gesture, GestureDetector } from "react-native-gesture-handler";
4+
import { runOnJS } from "react-native-reanimated";
5+
import DraggableFlatList, {
6+
ScaleDecorator,
7+
RenderItemParams,
8+
} from "react-native-draggable-flatlist";
9+
import { mapIndexToData, Item } from "../utils"
10+
11+
const NUM_ITEMS = 10;
12+
13+
const initialData: Item[] = [...Array(NUM_ITEMS)].map(mapIndexToData);
14+
15+
16+
17+
export default function Horizontal() {
18+
const [data, setData] = useState(initialData);
19+
20+
const renderItem = useCallback((params: RenderItemParams<Item>) => {
21+
const { item, drag, isActive } = params;
22+
const getPanGestureRef = (params as any).getPanGestureRef as (() => any) | undefined;
23+
const longPress = Gesture.LongPress()
24+
.minDuration(200)
25+
.onStart(() => runOnJS(drag)());
26+
if (getPanGestureRef) {
27+
const panRef = getPanGestureRef();
28+
if (panRef) longPress.simultaneousWithExternalGesture(panRef);
29+
}
30+
return (
31+
<ScaleDecorator>
32+
<GestureDetector gesture={longPress}>
33+
<TouchableOpacity
34+
activeOpacity={1}
35+
disabled={isActive}
36+
style={[
37+
styles.rowItem,
38+
{
39+
opacity: isActive ? 0.5 : 1,
40+
padding: 5,
41+
backgroundColor: item.backgroundColor,
42+
},
43+
]}
44+
>
45+
<Text style={styles.text}>{item.text}</Text>
46+
</TouchableOpacity>
47+
</GestureDetector>
48+
</ScaleDecorator>
49+
);
50+
}, []);
51+
52+
return (
53+
<View style={{ flex: 1 }}>
54+
<DraggableFlatList
55+
horizontal
56+
57+
data={data}
58+
onDragEnd={({ data }) => setData(data)}
59+
keyExtractor={(item) => {
60+
return item.key
61+
}}
62+
renderItem={renderItem}
63+
renderPlaceholder={() => <View style={{ flex: 1, backgroundColor: 'tomato' }} />}
64+
/>
65+
</View>
66+
);
67+
}
68+
69+
const styles = StyleSheet.create({
70+
rowItem: {
71+
height: 100,
72+
width: 100,
73+
alignItems: "center",
74+
justifyContent: "center",
75+
},
76+
text: {
77+
color: "white",
78+
fontSize: 24,
79+
fontWeight: "bold",
80+
textAlign: "center",
81+
},
82+
});

0 commit comments

Comments
 (0)