Skip to content

Commit 8c13333

Browse files
author
siamak
committed
switch button react native
1 parent dc06922 commit 8c13333

File tree

1 file changed

+218
-0
lines changed

1 file changed

+218
-0
lines changed

SwitchButton.js

Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
2+
/*
3+
4+
how to use:
5+
6+
1) import component
7+
2) set activeSwitch=1 to state
8+
3) use <MySwitchButton onValueChange={(val) => this.setState({ ttttt: val })} /> in your code
9+
4) use { this.state.activeSwitch === 1 ? view1 : view2 }
10+
11+
small example: ...
12+
13+
14+
constructor () {
15+
super();
16+
17+
this.state = {
18+
activeSwitch: 1
19+
};
20+
}
21+
22+
23+
render () {
24+
25+
return (
26+
27+
<View>
28+
<SwitchButton
29+
onValueChange={(val) => this.setState({ activeSwitch: val })} // this is necessary for this component
30+
text1 = 'ON' // optional: first text in switch button --- default ON
31+
text2 = 'OFF' // optional: second text in switch button --- default OFF
32+
switchWidth = {100} // optional: switch width --- default 44
33+
switchHeight = {44} // optional: switch height --- default 100
34+
switchdirection = 'rtl' // optional: switch button direction ( ltr and rtl ) --- default ltr
35+
switchBorderRadius = {100} // optional: switch border radius --- default oval
36+
switchSpeedChange = {500} // optional: button change speed --- default 100
37+
switchBorderColor = '#d4d4d4' // optional: switch border color --- default #d4d4d4
38+
switchBackgroundColor = '#fff' // optional: switch background color --- default #fff
39+
btnBorderColor = '#00a4b9' // optional: button border color --- default #00a4b9
40+
btnBackgroundColor = '#00bcd4' // optional: button background color --- default #00bcd4
41+
fontColor = '#b1b1b1' // optional: text font color --- default #b1b1b1
42+
activeFontColor = '#fff' // optional: active font color --- default #fff
43+
/>
44+
</View>
45+
46+
);
47+
}
48+
49+
50+
*/
51+
52+
import React, { Component } from 'react';
53+
import {
54+
View,
55+
Text,
56+
TouchableOpacity,
57+
StyleSheet,
58+
Animated
59+
} from 'react-native';
60+
import PropTypes from 'prop-types';
61+
62+
export default class SwitchButton extends Component {
63+
64+
static propTypes = {
65+
onValueChange: PropTypes.func
66+
};
67+
68+
static defaultProps = {
69+
onValueChange: () => null
70+
};
71+
72+
constructor() {
73+
super();
74+
75+
this.state = {
76+
activeSwitch: 1,
77+
sbWidth: 100,
78+
sbHeight: 44,
79+
direction: 'ltr',
80+
offsetX: new Animated.Value(0)
81+
};
82+
83+
this._switchDirection = this._switchDirection.bind(this);
84+
}
85+
86+
_switchDirection(direction) {
87+
let dir = 'row';
88+
89+
if (direction === 'rtl') {
90+
dir = 'row-reverse';
91+
}
92+
else {
93+
dir = 'row';
94+
}
95+
return dir;
96+
}
97+
98+
_switchThump(direction) {
99+
const { onValueChange, disabled } = this.props;
100+
let dirsign = 1;
101+
if (direction === 'rtl') {
102+
dirsign = -1;
103+
}
104+
else {
105+
dirsign = 1;
106+
}
107+
108+
if (this.state.activeSwitch === 1){
109+
this.setState({ activeSwitch: 2 }, () => onValueChange(this.state.activeSwitch));
110+
111+
Animated.timing(
112+
this.state.offsetX,
113+
{
114+
toValue: (((this.props.switchWidth || this.state.sbWidth) / 2) - 6) * dirsign,
115+
duration: this.props.switchSpeedChange || 100
116+
}
117+
).start();
118+
}
119+
else {
120+
this.setState({ activeSwitch: 1 }, () => onValueChange(this.state.activeSwitch));
121+
Animated.timing(
122+
this.state.offsetX,
123+
{
124+
toValue: 0,
125+
duration: this.props.switchSpeedChange || 100
126+
}
127+
).start();
128+
}
129+
130+
}
131+
132+
render() {
133+
134+
return (
135+
136+
<View>
137+
<TouchableOpacity activeOpacity={1} onPress={ () => { this._switchThump(this.props.switchdirection || this.state.direction) } }>
138+
<View
139+
style={[{
140+
width: this.props.switchWidth || this.state.sbWidth,
141+
height: this.props.switchHeight || this.state.sbHeight,
142+
borderRadius: this.props.switchBorderRadius !== undefined ? this.props.switchBorderRadius : this.state.sbHeight / 2,
143+
borderWidth: 1,
144+
borderColor: this.props.switchBorderColor || "#d4d4d4",
145+
backgroundColor: this.props.switchBackgroundColor || "#fff"
146+
}]}
147+
>
148+
<View style={[{ flexDirection: this._switchDirection(this.props.switchdirection || this.state.direction) }]} >
149+
150+
<Animated.View style={{ transform: [{translateX: this.state.offsetX }] }}>
151+
<View
152+
style={[switchStyles.wayBtnActive,
153+
{
154+
width: this.props.switchWidth / 2 || this.state.sbWidth / 2,
155+
height: this.props.switchHeight - 6 || this.state.sbHeight - 6,
156+
borderRadius: this.props.switchBorderRadius !== undefined ? this.props.switchBorderRadius : this.state.sbHeight / 2,
157+
borderColor: this.props.btnBorderColor || "#00a4b9",
158+
backgroundColor: this.props.btnBackgroundColor || "#00bcd4"
159+
}]}
160+
/>
161+
</Animated.View>
162+
163+
<View style={[switchStyles.textPos,
164+
{
165+
width: this.props.switchWidth / 2 || this.state.sbWidth / 2,
166+
height: this.props.switchHeight - 6 || this.state.sbHeight - 6,
167+
left: 0
168+
}]}
169+
>
170+
<Text style={[ this.state.activeSwitch === 1 ? { color: this.props.activeFontColor || "#fff" } : { color: this.props.fontColor || "#b1b1b1" } ]}>
171+
{ this.props.text1 || 'ON' }
172+
</Text>
173+
</View>
174+
175+
<View
176+
style={[switchStyles.textPos,
177+
{
178+
width: this.props.switchWidth / 2 || this.state.sbWidth / 2,
179+
height: this.props.switchHeight - 6 || this.state.sbHeight - 6,
180+
right:0
181+
}]}
182+
>
183+
<Text style={[ this.state.activeSwitch === 2 ? { color: this.props.activeFontColor || "#fff" } : { color: this.props.fontColor || "#b1b1b1" } ]}>
184+
{ this.props.text2 || 'OFF' }
185+
</Text>
186+
</View>
187+
</View>
188+
189+
</View>
190+
</TouchableOpacity>
191+
{ this.props.children }
192+
</View>
193+
194+
);
195+
}
196+
197+
}
198+
199+
const switchStyles = StyleSheet.create({
200+
textPos: {
201+
position: 'absolute',
202+
justifyContent: 'center',
203+
alignItems: 'center'
204+
},
205+
rtl: {
206+
flexDirection: 'row-reverse'
207+
},
208+
ltr: {
209+
flexDirection: 'row'
210+
},
211+
wayBtnActive: {
212+
borderWidth: 1,
213+
marginTop: 2,
214+
marginRight: 2,
215+
marginLeft: 2
216+
}
217+
218+
});

0 commit comments

Comments
 (0)