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