【发布时间】:2020-07-25 08:45:12
【问题描述】:
我正在让 Tinder 在我的应用中滑动。我正在使用FlatList 来渲染像 Tinder 这样的卡片组。我已将position:absolute 分配给我的FlatList 中的renderItems 的根视图,这样每个FlatList 项目都在彼此后面,我可以滑动查看下一个项目。 FlatList 中的每张卡片都非常复杂,因此我必须使用 scrollview 来垂直滚动每张卡片,并且我禁用了平面列表滚动,因为我不希望平面列表滚动,因为项目放在一个后面其他。现在position:absolute 在 iOS 上可以正常工作,但在 android 上不行。我厌倦了将left, top,right and bottom 属性分配给父视图,但它仍然不起作用。我也试过elevation。我可以使用 map 而不是 flatlist,但是性能真的很差,因为数组中有很多项目,并且在使用 map 在 android 和 ios 上工作时保持position:absolute。我尝试使用 https://github.com/alexbrillant/react-native-deck-swiper 和 https://github.com/archriss/react-native-snap-carousel,但由于我的 UI 的复杂性,它们并不能真正为我工作。
以下是 Flatlist 中每个项目的简单示例
return (
<Animated.View
{...panResponder.panHandlers}
style={[
rotateAndTranslate,
{
top: 0,
left: 0,
right: 0,
bottom: 0,
position: "absolute",
elevation: 1000,
},
]}
>
<Text>{index}</Text>
</Animated.View>
);
我在 flatlist 中的实际项目比上面的代码复杂得多。我尝试阅读有关此问题的不同 GitHub 问题以及堆栈溢出问题,但它们似乎对我不起作用。
我将这个 repo https://github.com/PlatypusIndustries/RNCardStack 称为 Tinder Swiping 的示例
如何在Android中将FlatList的每一项设置为绝对位置?
编辑:
通过将以下属性添加到我的 FlatList contentContainerStyle={{flexGrow:1,borderWidth:1}},我能够在 Android 中显示项目,但我的 FlatList 中每个项目的平移响应器在 Android 上不起作用,因为每个项目的位置都是绝对的。我也尝试添加elevation,zIndex,top,left,right,bottom 属性。我尝试将Animated.View 包装在View 中并将位置应用于该视图,但仍然无法在Android 中工作。我尝试将其包装在 TouchableOpacity 和 TouchableWithoutFeedback 中,但它不起作用。我尝试了来自react-native 和react-native-gesture-handler 的TouchableOpacity 和TouchableWithoutFeedback。当我删除 position:absolute 时,我的 Pan 响应程序代码有效,所以那里没有问题
这是我的 pan 响应器代码
let position = useRef(new Animated.ValueXY()).current;
// const [currentIndex, setCurrentIndex] = useState(0);
let rotate = position.x.interpolate({
inputRange: [-width / 2, 0, width / 2],
outputRange: ["-30deg", "0deg", "10deg"],
extrapolate: "clamp",
});
let rotateAndTranslate = {
transform: [
{
rotate: rotate,
},
...position.getTranslateTransform(),
],
};
let likeOpacity = position.x.interpolate({
inputRange: [-width / 2, 0, width / 2],
outputRange: [0, 0, 1],
extrapolate: "clamp",
});
let dislikeOpacity = position.x.interpolate({
inputRange: [-width / 2, 0, width / 2],
outputRange: [1, 0, 0],
extrapolate: "clamp",
});
const panResponder = PanResponder.create({
// onShouldBlockNativeResponder: () => true,
onMoveShouldSetPanResponderCapture: (event, gestureState) => {
// console.log(gestureState.dx);
if (gestureState.dx === 0 || gestureState.dy === 0) {
return false;
}
return true;
},
onPanResponderTerminationRequest: () => false,
onStartShouldSetPanResponderCapture: () => false,
onStartShouldSetPanResponder: (evt, gestureState) => false,
onPanResponderMove: (evt, gestureState) => {
// console.log(gestureState.dx);
// console.log("here " + width * 0.1);
if (gestureState.dx < width * 0.1 && gestureState.dx > -width * 0.1) {
return true;
}
position.setValue({ x: gestureState.dx, y: gestureState.dy });
},
onPanResponderRelease: (evt, gestureState) => {
// console.log(gestureState.dx);
if (gestureState.dx > 120) {
// console.log(gestureState.dy);
Animated.spring(position, {
toValue: {
x: width + 100,
y: gestureState.dy,
},
useNativeDriver: true,
}).start(() => {
handleRemove(index);
});
} else if (gestureState.dx < -120) {
// console.log(gestureState.dy);
Animated.spring(position, {
toValue: { x: -width - 180, y: gestureState.dy },
useNativeDriver: true,
}).start(() => {
handleRemove(index);
});
} else {
Animated.spring(position, {
toValue: { x: 0, y: 0 },
friction: 10,
useNativeDriver: true,
}).start();
}
},
});
【问题讨论】:
-
能否展示
PanResponder相关代码和rotateAndTranslate样式? -
@VadimGoroshevsky 我已经添加了代码,请检查,我认为我的 pan 响应器代码没有问题,因为它在 iOS 上工作,即使位置是绝对的。当我删除位置绝对代码时,它甚至可以在 android 上运行
-
我已经在我的项目中创建了 tinder 选项卡,但由于保密协议,我无法共享代码。我将为火种标签制作单独的包装
-
@MuhammadNuman 您的平面列表中的每个项目是否也可以垂直滚动。
-
是的,它也可以垂直工作。您可以在 LinkedIn 上连接到我,并可以私聊。 numan.dev
标签: android react-native react-native-flatlist