mh-rn-component
Version:
78 lines (77 loc) • 2.14 kB
Flow
import React, { useEffect, useState, useMemo } from 'react'
import { View, Animated, TouchableWithoutFeedback, Easing, StyleSheet } from 'react-native';
type Props = {
checked?: boolean
onChange: (value: boolean) => void,
activeColor?: string
inactiveColor?: string
size?: number
disabled?: boolean
type?: string
}
const Switch = (
{
size = 30,
checked = false,
activeColor = "#0f59a4",
inactiveColor = "#dcdee0",
...rest }: Props) => {
const move = new Animated.Value(0)
const click = () => {
rest.onChange(!checked)
}
const moveInterpolate = move.interpolate({
inputRange: [0, size],
outputRange: [inactiveColor, activeColor]
})
useEffect(() => {
if (checked) {
Animated.timing(move, {
toValue: size,
duration: 300,
useNativeDriver: false,
easing: Easing.elastic(0.5),
}).start(() => {
!checked ? move.setValue(0) : move.setValue(size)
})
} else {
move.setValue(size)
Animated.timing(move, {
toValue: 0,
duration: 300,
useNativeDriver: false,
easing: Easing.elastic(0.5),
}).start(() => {
!checked ? move.setValue(0) : move.setValue(size)
})
}
}, [checked])
return (
<TouchableWithoutFeedback disabled={rest?.disabled} onPress={click}>
<Animated.View style={[
styles.switch,
{
width: size * 2,
height: size,
borderRadius: size / 2,
backgroundColor: moveInterpolate,
borderColor: moveInterpolate,
}]}>
<Animated.View style={{ transform: [{ translateX: move }] }}>
<View style={[styles.switch_node, { width: size - 1, height: size - 1, borderRadius: size / 2 }]}></View>
</Animated.View>
</Animated.View>
</TouchableWithoutFeedback>
)
}
const styles = StyleSheet.create({
switch: {
justifyContent: "center",
borderWidth: 1,
},
switch_node: {
backgroundColor: "#fff",
}
})
// todo 是否需要调整react.memo带来的性能影响,主要用来处理重新渲染
export default React.memo(Switch)