我的 React Native 0.64 应用程序使用 react-native-gesture-handler 1.16/react-native-reanimated 2.1 左右滑动图像。这个想法是当用户单击图片库中的图像时,该图像会占据全屏显示,并且可以通过向左或向右滑动来一张一张地查看图库中的其余图像。这是滑动工作的完整代码,但有一个问题:点击的图像不显示,但画廊中的第一张图像总是首先显示。如何登陆用户点击的图片?
import React, { useRef } from "react";
import { Dimensions, StyleSheet, View, Platform } from "react-native";
import FastImage from 'react-native-fast-image';
import Animated, {
useAnimatedStyle,
useSharedValue,
useAnimatedRef,
useAnimatedGestureHandler,
useAnimatedReaction,
withTiming,
withSpring,
useDerivedValue,
} from "react-native-reanimated";
import {
snapPoint,
} from "react-native-redash";
import {
PanGestureHandler,
PinchGestureHandler,
State,
TouchableOpacity,
} from "react-native-gesture-handler";
const { width, height } = Dimensions.get("window");
export default Swipe = ({route, navigation}) => {
const {images, initIndex} = route.params; //initIndex is the index of image clicked
console.log("route params swipe ", route.params);
const index = useSharedValue(initIndex);
const snapPoints = images.map((_, i) => i * -width);
const panRef = useAnimatedRef();
const pinchRef = useAnimatedRef();
const offsetX = initIndex ? useSharedValue(initIndex * -width) : useSharedValue(0); //The init offsetX is set according to initIndex a user clicked.
const translationX = useSharedValue(0);
const translateX = useSharedValue(0); //if translateX was assgined with offsetX, then swipe stops working
//for snap in swipe
const lowVal = useDerivedValue(() => {return (index.value + 1) * -width}); //shared value, with .value
const highVal = useDerivedValue(() => {return (index.value - 1) * -width}); //shared value, with .value
const snapPt = (e) => {
"worklet";
return snapPoint(translateX.value, e.velocityX, snapPoints);
};
const panHandler = useAnimatedGestureHandler(
{
onStart: () => {
translateX.value = offsetX.value; //As soon as a user swipe, this line allow the
//image is moved to initIndex-th image. But how to land on the image a user has clicked?
},
onActive: (event) => {
translateX.value = offsetX.value + event.translationX;
translationX.value = event.translationX;
},
onEnd: (event) => {
let val = snapPt(event);
let sp = Math.min(Math.max(lowVal.value, val), highVal.value); //clamp in RN redash
if (event.translationX !== 0) {
translateX.value = withTiming(sp);
offsetX.value = translateX.value;
};
//update index
index.value = Math.floor(translateX.value/-width);
},
}, []
)
const swipeStyle = useAnimatedStyle(() => {
return {
transform: [{ translateX: translateX.value}]
}
});
return (
<PanGestureHandler
onGestureEvent={panHandler}
ref={panRef}
minDist={10}
avgTouches
>
<Animated.View style={styles.container}>
<Animated.View
style={[{width: width * images.length, height, flexDirection: "row"}, swipeStyle]}
>
{images.map((img_source, i) => {
const isActive = useDerivedValue(() => {return index.value === i});
return (
<View key={i} style={styles.picture}>
<View style={[
styles.image,
]}>
<TouchableOpacity onPress={() => navigation.goBack()} style={styles.button}>
<View style={styles.button}>
<FastImage
source={{uri:img_source.path}}
resizeMode={FastImage.resizeMode.contain}
style={styles.image}
/>
</View>
</TouchableOpacity>
</View>
</View>
);
})}
</Animated.View>
</Animated.View>
</PanGestureHandler>
);
}
const styles = StyleSheet.create({
container: {
...StyleSheet.absoluteFillObject,
backgroundColor: "black",
},
picture: {
width,
height,
overflow: "hidden",
},
image: {
//...StyleSheet.absoluteFillObject,
flex:1,
width: undefined,
height: undefined,
//resizeMode: "cover",
},
button: {
width: width,
height:height,
},
});
代码的另一个问题是,在滑动图像之前触摸图像时,图像会向左或向右抖动 1/3-1/2 屏幕宽度。这使得滑动不流畅。我想知道如何消除图像抖动并使滑动从头到尾平滑。