之前一个小功能需要用到switch 这个控件, 后来发现这个控件在ios 和 android 的显示差异挺大的, 而且android 偶尔会出现控件不展示的情况,不知道大家有没有同样的问题, 后来决定自己撸一个试试。代码很平常,
import React, { Component } from 'react';
import { StyleSheet,Animated, TouchableOpacity} from 'react-native';
const styles = StyleSheet.create({
container: {
height: 30,
width: 50,
borderRadius: 15,
backgroundColor: '#32CDFF',
},
scaleBg:{
flex:1,
borderRadius: 15,
backgroundColor: '#E7E8EA',
},
toggleBtn: {
height: 28,
width: 28,
backgroundColor:'white',
borderRadius: 14,
position:'absolute',
top:1,
}
});
class Switch extends Component {
constructor(props) {
super(props);
this.state = {
toggleOn:false,
}
this.toggerPostion = new Animated.Value(1);
this.scaleBg = new Animated.Value(1);
}
componentDidMount(){
const {value } = this.props;
if(value ) {
this.setState({toggleOn:true})
Animated.timing(this.scaleBg,{toValue: 0.1,duration:400,}).start();
Animated.spring ( this.toggerPostion, {toValue: sceneScale* ( 50 - 29 ),},
).start();
}
}
toggleSwitch = ()=> {
const {onPress,useOnce,onValueChange} = this.props;
if(this.state.toggleOn && useOnce === undefined) {
this.setState({
toggleOn:false,
})
Animated.spring(this.toggerPostion,{toValue: 1,},).start();
Animated.timing(this.scaleBg,{toValue: 1, duration:400,}).start();
onValueChange(false);
} else {
this.setState({
toggleOn:true,
})
Animated.spring (this.toggerPostion,{toValue: sceneScale* ( 50 - 29 ),},).start();
Animated.timing(this.scaleBg,{toValue: 0.0,duration:400,}).start();
if(onPress){
setTimeout(()=>{onPress()},400);
}
onValueChange(true);
}
}
componentWillReceiveProps(nextProps){
if(this.props.value !== nextProps.value){
this.toggleSwitch();
}
}
render() {
return (
<TouchableOpacity style={[styles.container]} onPress={this.toggleSwitch} activeOpacity={1}>
<Animated.View style={[styles.scaleBg,{transform:[{scale:this.scaleBg}]}]}>
</Animated.View>
<Animated.View
style={[styles.toggleBtn , { left: this.toggerPostion }]}
></Animated.View>
</TouchableOpacity>
);
}
}
export default Switch;
控件的用法
this.state = {
toggle = 0;
}
setToggle = (switchValue) => {
this.setState({
toggle:switchValue,
})
<Switch
value={toggle}
onValueChange={(switchValue)=>this.setToggle(switchValue)}
/>
实现的方法比较直接, 就是控制在点击的时候按钮位置的变化,和背景的动画缩放. 效果如下
大家可以控件扩充一下, 实现大小, 颜色, 甚至动画效果的自定义。