自定义 react-native switch ,可以修改大小,颜色,背景等
```
import React, {Component }from "react";
import {
Text,
StyleSheet,
Animated,
TouchableWithoutFeedback,
ViewPropTypes
}from "react-native";
import PropTypesfrom "prop-types";
export default class Switchextends Component {
static propTypes = {
onValueChange: PropTypes.func,
disabled: PropTypes.bool,
activeText: PropTypes.string,
inActiveText: PropTypes.string,
backgroundActive: PropTypes.string,
backgroundInactive: PropTypes.string,
value: PropTypes.bool,
circleActiveColor: PropTypes.string,
circleInActiveColor: PropTypes.string,
circleSize: PropTypes.number,
circleBorderActiveColor: PropTypes.string,
circleBorderInactiveColor: PropTypes.string,
activeTextStyle:Text.propTypes.style,
inactiveTextStyle:Text.propTypes.style,
containerStyle:ViewPropTypes.style,
barHeight: PropTypes.number,
circleBorderWidth: PropTypes.number,
innerCircleStyle:ViewPropTypes.style,
renderInsideCircle: PropTypes.func,
changeValueImmediately: PropTypes.bool,
innerCircleStyle:ViewPropTypes.style,
outerCircleStyle:ViewPropTypes.style,
renderActiveText: PropTypes.bool,
renderInActiveText: PropTypes.bool,
switchLeftPx: PropTypes.number,
switchRightPx: PropTypes.number,
switchWidthMultiplier: PropTypes.number,
switchWidth: PropTypes.number
};
static defaultProps = {
value:false,
onValueChange: () =>null,
renderInsideCircle: () =>null,
innerCircleStyle: {},
disabled:false,
activeText:"On",
inActiveText:"Off",
backgroundActive:"green",
backgroundInactive:"gray",
circleActiveColor:"white",
circleInActiveColor:"white",
circleBorderActiveColor:"rgb(100, 100, 100)",
circleBorderInactiveColor:"rgb(80, 80, 80)",
circleSize:30,
barHeight:null,
circleBorderWidth:1,
changeValueImmediately:true,
innerCircleStyle: {alignItems:"center", justifyContent:"center" },
outerCircleStyle: {},
renderActiveText:false,
renderInActiveText:false,
switchLeftPx:2,
switchRightPx:2,
switchWidthMultiplier:1.5,
switchWidth:48
};
constructor(props, context) {
super(props, context);
this.state = {
value: props.value,
transformSwitch:new Animated.Value(
props.value
? (props.switchWidth-props.circleSize) / props.switchLeftPx
: -(props.switchWidth-props.circleSize) / props.switchRightPx
),
backgroundColor:new Animated.Value(props.value ?75 : -75),
circleColor:new Animated.Value(props.value ?75 : -75),
circleBorderColor:new Animated.Value(props.value ?75 : -75),
};
this.handleSwitch =this.handleSwitch.bind(this);
this.animateSwitch =this.animateSwitch.bind(this);
}
componentWillReceiveProps(nextProps) {
const {disabled } =this.props;
if (nextProps.value ===this.props.value) {
return;
}
if (disabled) {
return;
}
this.animateSwitch(nextProps.value, () => {
this.setState({value: nextProps.value });
});
}
handleSwitch() {
const {value } =this.state;
const {
onValueChange,
disabled,
changeValueImmediately,
value:propValue
} =this.props;
if (disabled) {
return;
}
if (changeValueImmediately) {
this.animateSwitch(!propValue);
onValueChange(!propValue);
}else {
this.animateSwitch(!value, () => {
this.setState({value: !value }, () =>onValueChange(this.state.value));
});
}
}
animateSwitch(value, cb = () => {}) {
Animated.parallel([
Animated.spring(this.state.transformSwitch, {
toValue: value
? (this.props.switchWidth-this.props.circleSize) /this.props.switchLeftPx
: -(this.props.switchWidth-this.props.circleSize) /this.props.switchRightPx
}),
Animated.timing(this.state.backgroundColor, {
toValue: value ?75 : -75,
duration:200
}),
Animated.timing(this.state.circleColor, {
toValue: value ?75 : -75,
duration:200
}),
Animated.timing(this.state.circleBorderColor, {
toValue: value ?75 : -75,
duration:200
}),
]).start(cb);
}
render() {
const {transformSwitch, backgroundColor, circleColor, circleBorderColor } =this.state;
const {
backgroundActive,
backgroundInactive,
circleActiveColor,
circleInActiveColor,
activeText,
inActiveText,
circleSize,
containerStyle,
activeTextStyle,
inactiveTextStyle,
barHeight,
circleInactiveBorderColor,
circleActiveBorderColor,
circleBorderWidth,
innerCircleStyle,
outerCircleStyle,
renderActiveText,
renderInActiveText,
renderInsideCircle,
switchWidthMultiplier,
switchWidth
} =this.props;
const interpolatedColorAnimation =backgroundColor.interpolate({
inputRange: [-75, 75],
outputRange: [backgroundInactive, backgroundActive]
});
const interpolatedCircleColor =circleColor.interpolate({
inputRange: [-75, 75],
outputRange: [circleInActiveColor, circleActiveColor]
});
const interpolatedCircleBorderColor =circleBorderColor.interpolate({
inputRange: [-75, 75],
outputRange: [circleInactiveBorderColor, circleActiveBorderColor]
});
return (
<TouchableWithoutFeedback onPress={this.handleSwitch}>
style={[
styles.container,
containerStyle,
{
backgroundColor: interpolatedColorAnimation,
width:switchWidth,
height:barHeight ||circleSize,
borderRadius:circleSize
}
]}
>
style={[
styles.animatedContainer,
{
left:transformSwitch,
width:switchWidth
},
outerCircleStyle
]}
>
{renderActiveText && (
<Text style={[styles.text, styles.paddingRight, activeTextStyle]}>
activeText
)}
style={[
styles.circle,
{
borderWidth:circleBorderWidth,
borderColor: interpolatedCircleBorderColor,
backgroundColor: interpolatedCircleColor,
width:circleSize,
height:circleSize,
borderRadius:circleSize /2
},
innerCircleStyle
]}
>
{renderInsideCircle()}
{renderInActiveText && (
style={[styles.text, styles.paddingLeft, inactiveTextStyle]}
>
{inActiveText}
)}
);
}
}
const styles =StyleSheet.create({
container: {
width:71,
height:30,
borderRadius:30,
backgroundColor:"black"
},
animatedContainer: {
flex:1,
width:78,
flexDirection:"row",
justifyContent:"center",
alignItems:"center"
},
circle: {
width:30,
height:30,
borderRadius:15,
backgroundColor:"white"
},
text: {
color:"white",
backgroundColor:"transparent"
},
paddingRight: {
paddingRight:5
},
paddingLeft: {
paddingLeft:5
}
});
```