import { useEffect } from 'react' import { Pressable, StyleSheet } from 'react-native' import Animated, { interpolateColor, useAnimatedStyle, useSharedValue, withTiming, } from 'react-native-reanimated' interface SwitchProps { value: any onChange: (val: any) => void trueValue?: any falseValue?: any width?: number height?: number activeColor?: string inactiveColor?: string duration?: number disabled?: boolean // 新增 disabled } export default function Switch({ value, onChange, trueValue, falseValue, width = 52, height = 24, activeColor = '#333', inactiveColor = '#e5e7eb', duration = 200, disabled = false, // 默认可用 }: SwitchProps) { // 默认值 fallback const trueVal = trueValue ?? true const falseVal = falseValue ?? false // 当前状态是否为激活 const isActive = Object.is(value, trueVal) // 控制动画的 sharedValue const progress = useSharedValue(isActive ? 1 : 0) useEffect(() => { progress.value = withTiming(isActive ? 1 : 0, { duration }) }, [isActive, duration]) const knobSize = height - 4 const translateX = width - knobSize - 4 // 动画轨道样式 const trackStyle = useAnimatedStyle(() => { const baseColor = interpolateColor( progress.value, [0, 1], [inactiveColor, activeColor], ) return { backgroundColor: baseColor, opacity: disabled ? 0.7 : 1, // disabled 半透明 } }) // 动画滑块样式 const knobStyle = useAnimatedStyle(() => { return { transform: [ { translateX: progress.value * translateX, }, ], opacity: disabled ? 0.8 : 1, // knob 半透明 } }) return ( { if (disabled) return const nextValue = isActive ? falseVal : trueVal onChange(nextValue) }} style={{ width, height }} > ) } const styles = StyleSheet.create({ track: { justifyContent: 'center', padding: 2, }, knob: { backgroundColor: '#fff', elevation: 2, shadowColor: '#000', shadowOpacity: 0.2, shadowRadius: 2, shadowOffset: { width: 0, height: 1 }, }, })