React Native 平移手势处理程序不起作用
React Native pan gesture handler not working
-
javascript
-
react-native
-
react-native-reanimated
-
react-native-gesture-handler
-
react-native-reanimated-v2
我正在学习这个教程:https://youtu.be/r5XXSb4yQes (code: https://github.com/wcandillon/can-it-be-done-in-react-native/tree/master/season3/src/CoinbasePro) 并按照他说的做了,但我无法使洗涤器(水平和垂直线)工作。
如你所见,即使我press/drag,scrubber/line也没有出现。
预期触发PanGestureHandler时的横竖线:
相关代码如下:
主屏幕:
import Animated, {
add,
diffClamp,
eq,
modulo,
sub,
} from "react-native-reanimated";
import { useValues, onGestureEvent } from "react-native-redash/lib/module/v1";
import { PanGestureHandler, State } from "react-native-gesture-handler";
import Svg, { Line } from "react-native-svg";
import data from "../../utils/data";
const MainScreen = () => {
const caliber = data.length > 0 ? width / data.length : 0;
const [x, y, state] = useValues(0, 0, State.UNDETERMINED);
const gestureHandler = onGestureEvent({ x, y, state });
const opacity = eq(state, State.ACTIVE);
const translateY = diffClamp(y, 0, width);
const translateX = add(sub(x, modulo(x, caliber)), caliber / 2);
return (
<View style={styles.container}>
{/* CHART INFO START */}
<Animated.View style={{ opacity }} pointerEvents="none">
<ChartInfo candles={data} translateX={translateX} caliber={caliber} />
</Animated.View>
{/* CHART INFO END */}
<View>
{/* CHART START */}
<Chart
candles={data}
size={width}
caliber={caliber}
domain={calculateMinMaxCandles(data)}
/>
{/* CHART END */}
<PanGestureHandler minDist={0} {...gestureHandler}>
<Animated.View style={StyleSheet.absoluteFill}>
{/* HORIZONTAL LINE START */}
<Animated.View
style={{
...StyleSheet.absoluteFillObject,
opacity,
transform: [{ translateY }],
}}
>
<ScrubberLine x={width} y={0} />
</Animated.View>
{/* HORIZONTAL LINE END */}
{/* VERTICAL LINE START */}
<Animated.View
style={{
...StyleSheet.absoluteFillObject,
opacity,
transform: [{ translateX }],
}}
>
<ScrubberLine x={0} y={width} />
</Animated.View>
{/* VERTICAL LINE END */}
</Animated.View>
</PanGestureHandler>
</View>
</View>
);
}
const ScrubberLine = ({ x, y }) => {
return (
<Svg style={StyleSheet.absoluteFill}>
<Line
x1={0}
y1={0}
x2={x}
y2={y}
strokeWidth={2}
stroke="#B5B6B7"
strokeDasharray="6 6"
/>
</Svg>
);
};
ChartInfo.js
import { SafeAreaView } from "react-native-safe-area-context";
import {
call,
divide,
floor,
onChange,
useCode,
} from "react-native-reanimated";
import * as Haptics from "expo-haptics";
import styles from "./style";
const ChartInfo = ({ translateX, caliber, candles }) => {
const [{ timestamp, open, close, high, low }, setCandle] = useState(
candles[0]
);
useCode(
() =>
onChange(
translateX,
call([floor(divide(translateX, caliber))], ([index]) => {
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
setCandle(candles[index]);
})
),
[caliber, candles, translateX]
);
const diff = `${((close - open) * 100) / open}`;
const change = close - open < 0 ? diff.substring(0, 5) : diff.substring(0, 4);
return (
<SafeAreaView style={styles.container}>
<View style={styles.table}>
<View style={styles.column}>
<Row label="Open" value={open} />
<Row label="Close" value={close} />
<Row label="Volume" value="" />
</View>
<View style={styles.separator} />
<View style={styles.column}>
<Row label="High" value={high} />
<Row label="Low" value={low} />
<Row
label="Change"
value={`${change}%`}
color={close - open > 0 ? "#4AFA9A" : "#E33F64"}
/>
</View>
</View>
</SafeAreaView>
);
};
export default ChartInfo;
const Row = ({ label, value }) => (
<View style={styles.rowContainer}>
<Text style={styles.label}>{label}</Text>
<Text style={styles.value}>{value}</Text>
</View>
);
package.json:
"dependencies": {
"@react-navigation/native": "^6.0.6",
"@react-navigation/native-stack": "^6.2.5",
"d3-scale": "^4.0.2",
"expo": "~44.0.0",
"expo-haptics": "~11.1.0",
"expo-status-bar": "~1.2.0",
"react": "17.0.1",
"react-dom": "17.0.1",
"react-native": "0.64.3",
"react-native-gesture-handler": "~2.1.0",
"react-native-haptic-feedback": "^1.13.0",
"react-native-reanimated": "~2.3.1",
"react-native-redash": "^16.2.3",
"react-native-safe-area-context": "3.3.2",
"react-native-screens": "~3.10.1",
"react-native-svg": "^12.1.1",
"react-native-web": "0.17.1"
},
"devDependencies": {
"@babel/core": "^7.12.9"
},
我调试了好几天了,也找不到哪里不对,跟他教程里说的一模一样。有人可以帮帮我吗!
将其全部包装在 GestureHandlerRootView 中,像这样
import {GestureHandlerRootView} from 'react-native-gesture-handler'
...
return(
<GestureHandlerRootView>
{...} Your views
</GestureHandlerRootView>
应该可以。
javascript
react-native
react-native-reanimated
react-native-gesture-handler
react-native-reanimated-v2
我正在学习这个教程:https://youtu.be/r5XXSb4yQes (code: https://github.com/wcandillon/can-it-be-done-in-react-native/tree/master/season3/src/CoinbasePro) 并按照他说的做了,但我无法使洗涤器(水平和垂直线)工作。
如你所见,即使我press/drag,scrubber/line也没有出现。
预期触发PanGestureHandler时的横竖线:
相关代码如下:
主屏幕:
import Animated, {
add,
diffClamp,
eq,
modulo,
sub,
} from "react-native-reanimated";
import { useValues, onGestureEvent } from "react-native-redash/lib/module/v1";
import { PanGestureHandler, State } from "react-native-gesture-handler";
import Svg, { Line } from "react-native-svg";
import data from "../../utils/data";
const MainScreen = () => {
const caliber = data.length > 0 ? width / data.length : 0;
const [x, y, state] = useValues(0, 0, State.UNDETERMINED);
const gestureHandler = onGestureEvent({ x, y, state });
const opacity = eq(state, State.ACTIVE);
const translateY = diffClamp(y, 0, width);
const translateX = add(sub(x, modulo(x, caliber)), caliber / 2);
return (
<View style={styles.container}>
{/* CHART INFO START */}
<Animated.View style={{ opacity }} pointerEvents="none">
<ChartInfo candles={data} translateX={translateX} caliber={caliber} />
</Animated.View>
{/* CHART INFO END */}
<View>
{/* CHART START */}
<Chart
candles={data}
size={width}
caliber={caliber}
domain={calculateMinMaxCandles(data)}
/>
{/* CHART END */}
<PanGestureHandler minDist={0} {...gestureHandler}>
<Animated.View style={StyleSheet.absoluteFill}>
{/* HORIZONTAL LINE START */}
<Animated.View
style={{
...StyleSheet.absoluteFillObject,
opacity,
transform: [{ translateY }],
}}
>
<ScrubberLine x={width} y={0} />
</Animated.View>
{/* HORIZONTAL LINE END */}
{/* VERTICAL LINE START */}
<Animated.View
style={{
...StyleSheet.absoluteFillObject,
opacity,
transform: [{ translateX }],
}}
>
<ScrubberLine x={0} y={width} />
</Animated.View>
{/* VERTICAL LINE END */}
</Animated.View>
</PanGestureHandler>
</View>
</View>
);
}
const ScrubberLine = ({ x, y }) => {
return (
<Svg style={StyleSheet.absoluteFill}>
<Line
x1={0}
y1={0}
x2={x}
y2={y}
strokeWidth={2}
stroke="#B5B6B7"
strokeDasharray="6 6"
/>
</Svg>
);
};
ChartInfo.js
import { SafeAreaView } from "react-native-safe-area-context";
import {
call,
divide,
floor,
onChange,
useCode,
} from "react-native-reanimated";
import * as Haptics from "expo-haptics";
import styles from "./style";
const ChartInfo = ({ translateX, caliber, candles }) => {
const [{ timestamp, open, close, high, low }, setCandle] = useState(
candles[0]
);
useCode(
() =>
onChange(
translateX,
call([floor(divide(translateX, caliber))], ([index]) => {
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
setCandle(candles[index]);
})
),
[caliber, candles, translateX]
);
const diff = `${((close - open) * 100) / open}`;
const change = close - open < 0 ? diff.substring(0, 5) : diff.substring(0, 4);
return (
<SafeAreaView style={styles.container}>
<View style={styles.table}>
<View style={styles.column}>
<Row label="Open" value={open} />
<Row label="Close" value={close} />
<Row label="Volume" value="" />
</View>
<View style={styles.separator} />
<View style={styles.column}>
<Row label="High" value={high} />
<Row label="Low" value={low} />
<Row
label="Change"
value={`${change}%`}
color={close - open > 0 ? "#4AFA9A" : "#E33F64"}
/>
</View>
</View>
</SafeAreaView>
);
};
export default ChartInfo;
const Row = ({ label, value }) => (
<View style={styles.rowContainer}>
<Text style={styles.label}>{label}</Text>
<Text style={styles.value}>{value}</Text>
</View>
);
package.json:
"dependencies": {
"@react-navigation/native": "^6.0.6",
"@react-navigation/native-stack": "^6.2.5",
"d3-scale": "^4.0.2",
"expo": "~44.0.0",
"expo-haptics": "~11.1.0",
"expo-status-bar": "~1.2.0",
"react": "17.0.1",
"react-dom": "17.0.1",
"react-native": "0.64.3",
"react-native-gesture-handler": "~2.1.0",
"react-native-haptic-feedback": "^1.13.0",
"react-native-reanimated": "~2.3.1",
"react-native-redash": "^16.2.3",
"react-native-safe-area-context": "3.3.2",
"react-native-screens": "~3.10.1",
"react-native-svg": "^12.1.1",
"react-native-web": "0.17.1"
},
"devDependencies": {
"@babel/core": "^7.12.9"
},
我调试了好几天了,也找不到哪里不对,跟他教程里说的一模一样。有人可以帮帮我吗!
将其全部包装在 GestureHandlerRootView 中,像这样
import {GestureHandlerRootView} from 'react-native-gesture-handler'
...
return(
<GestureHandlerRootView>
{...} Your views
</GestureHandlerRootView>
应该可以。