import { View, Text, TouchableOpacity, Modal, PanResponder, Dimensions, } from "react-native"; import React, { useState, useEffect, useRef } from "react"; import { useTailwind } from "tailwind-rn"; import { Image } from "expo-image"; export default function MySlider({ lower_bound, upper_bound, step, unit, lable, height = 60, width = Dimensions.get("window").width - 48, onChange, onAfterChange = () => {}, defaultValue = 0, disabled = false, thumbSize = 25, stepValues = [], itemKey, hasInfinity, leftValue = 0, rightValue = 0, thumbImage = null, maximumTrackTintColor = "#dcdbdb", minimumTrackTintColor = "#577BFF", processHeight = 7, }) { // const leftProcess = useRef(0); // const rightProcess = useRef(0); const [leftProcess, setLeftProcess] = useState(0); const [rightProcess, setRightProcess] = useState(0); const [stepNum, setStepNum] = useState(stepValues.length - 1); const [processWidth, setProcessWidth] = useState(330); const tailwind = useTailwind(); const leftWatcher = useRef(null); const rightWatcher = useRef(null); useEffect(() => { leftWatcher.current = PanResponder.create({ // 建立监视器 onStartShouldSetPanResponder: () => true, onPanResponderGrant: _onPanResponderGrantLeft, // 按下 onPanResponderMove: _onPanResponderMoveLeft, // 移动 onPanResponderEnd: _onPanResponderEndLeft, // 结束 }); rightWatcher.current = PanResponder.create({ // 建立监视器 onStartShouldSetPanResponder: () => true, onPanResponderGrant: _onPanResponderGrantRight, // 按下 onPanResponderMove: _onPanResponderMoveRight, // 移动 onPanResponderEnd: _onPanResponderEndRight, // 结束 }); setProcessWidth(width - thumbSize * 2); }, []); useEffect(() => { // if(itemKey) const currentLeftProcess = 0; const currentRightProcess = (stepValues.indexOf(rightValue) * step - lower_bound) / (upper_bound - lower_bound); setLeftProcess(currentLeftProcess); setRightProcess(currentRightProcess); }, [leftValue, rightValue]); // useEffect(() => { // }, [leftProcess, rightProcess]); // 左侧滑块事件 const _onPanResponderGrantLeft = (e, gestureState) => { const process = (gestureState.x0 - 40 - thumbSize / 2) / processWidth; _changeProcess(process, "left"); }; const _onPanResponderEndLeft = (e, gestureState) => { if (onAfterChange) { onAfterChange(gestureState.x0); } }; const _onPanResponderMoveLeft = (e, gestureState) => { const process = (gestureState.x0 - 40 - thumbSize / 2 + gestureState.dx) / processWidth; _changeProcess(process, "left"); }; // 右侧滑块事件 const _onPanResponderGrantRight = (e, gestureState) => { const process = (gestureState.x0 - 40 - thumbSize / 2) / processWidth; _changeProcess(process, "right"); }; const _onPanResponderEndRight = (e, gestureState) => { if (onAfterChange) { onAfterChange(gestureState.x0); } }; const _onPanResponderMoveRight = (e, gestureState) => { const process = (gestureState.x0 - 40 - thumbSize / 2 + gestureState.dx) / processWidth; _changeProcess(process, "right"); }; const _changeProcess = (changeProcess, direction) => { // 判断滑动开关 if (disabled) return; if (changeProcess >= 0 && changeProcess <= 1) { // 按步长比例变化刻度 const v = changeProcess * (upper_bound - lower_bound); const newValue = Math.round(v / step) * step; const newProcess = Math.round(newValue) / (upper_bound - lower_bound); setStepNum(stepNum + 1); if (process !== newProcess) { if (direction == "left") { if (newProcess < rightProcess) { setLeftProcess(newProcess); setStepNum((old) => old + 1); onChange({ lower_bound: Math.round( leftProcess * (upper_bound - lower_bound) + lower_bound ), upper_bound: rightValue, }); } } else { if (newProcess > leftProcess) { // rightProcess.current = newProcess; setRightProcess(newProcess); setStepNum((old) => old - 1); onChange({ lower_bound: leftValue, upper_bound: stepValues[ Math.round( (newProcess * (upper_bound - lower_bound) + lower_bound) / step ) ], }); // setStepNum(stepNum - 1); } } } } }; return ( {Math.round(leftProcess * (upper_bound - lower_bound) + lower_bound)} - {hasInfinity && rightProcess == 1 ? ">" + upper_bound : stepValues[ Math.round( (rightProcess * (upper_bound - lower_bound) + lower_bound) / step ) ]} {unit} {lower_bound} {hasInfinity ? ">" + upper_bound : upper_bound} ); }