11import assign from 'assign-deep' ;
22import React , { Component , PropTypes } from 'react' ;
33import {
4+ StatusBar ,
45 StyleSheet ,
56 Text ,
67 View ,
@@ -11,6 +12,10 @@ import {
1112 Platform ,
1213} from 'react-native' ;
1314import Swiper from 'react-native-swiper' ;
15+ import DoneButton from './components/DoneButton' ;
16+ import SkipButton from './components/SkipButton' ;
17+ import RenderDots from './components/Dots' ;
18+
1419const windowsWidth = Dimensions . get ( 'window' ) . width ;
1520const windowsHeight = Dimensions . get ( 'window' ) . height ;
1621
@@ -62,13 +67,6 @@ const defaulStyles = {
6267 } ,
6368 activeDotStyle : {
6469 backgroundColor : '#fff' ,
65- width : 13 ,
66- height : 13 ,
67- borderRadius : 7 ,
68- marginLeft : 7 ,
69- marginRight : 7 ,
70- marginTop : 7 ,
71- marginBottom : 7 ,
7270 } ,
7371 paginationContainer : {
7472 position : 'absolute' ,
@@ -189,21 +187,6 @@ export default class AppIntro extends Component {
189187 }
190188
191189 renderPagination = ( index , total , context ) => {
192- const { activeDotColor, dotColor, rightTextColor, leftTextColor } = this . props ;
193- const ActiveDot = (
194- < View
195- style = { [ this . styles . activeDotStyle , { backgroundColor : activeDotColor } ] }
196- />
197- ) ;
198- const Dot = < View style = { [ this . styles . dotStyle , { backgroundColor : dotColor } ] } /> ;
199- let dots = [ ] ;
200- for ( let i = 0 ; i < total ; i ++ ) {
201- dots . push ( i === index ?
202- React . cloneElement ( ActiveDot , { key : i } )
203- :
204- React . cloneElement ( Dot , { key : i } )
205- ) ;
206- }
207190 let isDoneBtnShow ;
208191 let isSkipBtnShow ;
209192 if ( index === total - 1 ) {
@@ -219,91 +202,31 @@ export default class AppIntro extends Component {
219202 isDoneBtnShow = false ;
220203 isSkipBtnShow = true ;
221204 }
222- let controllBts ;
223- if ( Platform . OS === 'ios' ) {
224- controllBts = (
225- < View style = { this . styles . paginationContainer } >
226- < Animated . View style = { [ this . styles . btnContainer , {
227- opacity : this . state . skipFadeOpacity ,
228- transform : [ {
229- translateX : this . state . skipFadeOpacity . interpolate ( {
230- inputRange : [ 0 , 1 ] ,
231- outputRange : [ 0 , 15 ] ,
232- } ) ,
233- } ] ,
234- } ] }
235- >
236- < TouchableOpacity
237- style = { this . styles . full }
238- onPress = { isSkipBtnShow ? ( ) => this . props . onSkipBtnClick ( index ) : null }
239- >
240- < Text style = { [ this . styles . controllText , { color : leftTextColor } ] } > { this . props . skipBtnLabel } </ Text >
241- </ TouchableOpacity >
242- </ Animated . View >
243- < View style = { this . styles . dotContainer } >
244- { dots }
245- </ View >
246- < View style = { this . styles . btnContainer } >
247- < Animated . View style = { [ this . styles . full , { height : 0 } , {
248- opacity : this . state . doneFadeOpacity ,
249- transform : [ {
250- translateX : this . state . skipFadeOpacity . interpolate ( {
251- inputRange : [ 0 , 1 ] ,
252- outputRange : [ 0 , 20 ] ,
253- } ) ,
254- } ] ,
255- } ] }
256- >
257- < View style = { this . styles . full } >
258- < Text style = { [ this . styles . controllText , {
259- color : rightTextColor , paddingRight : 30 ,
260- } ] }
261- > { this . props . doneBtnLabel } </ Text >
262- </ View >
263- </ Animated . View >
264- < Animated . View style = { [ this . styles . full , { height : 0 } , { opacity : this . state . nextOpacity } ] } >
265- < TouchableOpacity style = { this . styles . full }
266- onPress = { isDoneBtnShow ?
267- this . props . onDoneBtnClick : this . onNextBtnClick . bind ( this , context ) }
268- >
269- < Text style = { [ this . styles . nextButtonText , { color : rightTextColor } ] } > { this . props . nextBtnLabel } </ Text >
270- </ TouchableOpacity >
271- </ Animated . View >
272- </ View >
273- </ View >
274- ) ;
275- } else {
276- controllBts = (
277- < View style = { this . styles . paginationContainer } >
278- < View style = { [ this . styles . btnContainer , {
279- paddingBottom : 5 ,
280- opacity : isSkipBtnShow ? 1 : 0 ,
281- } ] }
282- >
283- < TouchableOpacity
284- style = { this . styles . full }
285- onPress = { isSkipBtnShow ? ( ) => this . props . onSkipBtnClick ( index ) : null }
286- >
287- < Text style = { [ this . styles . controllText , { color : leftTextColor } ] } > { this . props . skipBtnLabel } </ Text >
288- </ TouchableOpacity >
289- </ View >
290- < View style = { this . styles . dotContainer } >
291- { dots }
292- </ View >
293- < View style = { [ this . styles . btnContainer , { height : 0 , paddingBottom : 5 } ] } >
294- < TouchableOpacity style = { this . styles . full }
295- onPress = { isDoneBtnShow ?
296- this . props . onDoneBtnClick : this . onNextBtnClick . bind ( this , context ) }
297- >
298- < Text style = { [ this . styles . nextButtonText , { color : rightTextColor } ] } >
299- { isDoneBtnShow ? this . props . doneBtnLabel : this . props . nextBtnLabel }
300- </ Text >
301- </ TouchableOpacity >
302- </ View >
303- </ View >
304- ) ;
305- }
306- return controllBts ;
205+ return (
206+ < View style = { [ this . styles . paginationContainer ] } >
207+ { this . props . showSkipButton ? < SkipButton
208+ { ...this . props }
209+ { ...this . state }
210+ isSkipBtnShow = { isSkipBtnShow }
211+ styles = { this . styles }
212+ onSkipBtnClick = { ( ) => this . props . onSkipBtnClick ( index ) } /> :
213+ < View style = { this . styles . btnContainer } />
214+ }
215+ { this . props . showDots && RenderDots ( index , total , {
216+ ...this . props ,
217+ styles : this . styles
218+ } ) }
219+ { this . props . showDoneButton ? < DoneButton
220+ { ...this . props }
221+ { ...this . state }
222+ isDoneBtnShow = { isDoneBtnShow }
223+ styles = { this . styles }
224+ onNextBtnClick = { this . onNextBtnClick . bind ( this , context ) }
225+ onDoneBtnClick = { this . props . onDoneBtnClick } /> :
226+ < View style = { this . styles . btnContainer } />
227+ }
228+ </ View >
229+ ) ;
307230 }
308231
309232 renderBasicSlidePage = ( index , {
@@ -318,10 +241,11 @@ export default class AppIntro extends Component {
318241 const AnimatedStyle1 = this . getTransform ( index , 10 , level ) ;
319242 const AnimatedStyle2 = this . getTransform ( index , 0 , level ) ;
320243 const AnimatedStyle3 = this . getTransform ( index , 15 , level ) ;
244+ const imgSource = ( typeof img === 'string' ) ? { uri : img } : img ;
321245 const pageView = (
322246 < View style = { [ this . styles . slide , { backgroundColor } ] } showsPagination = { false } key = { index } >
323247 < Animated . View style = { [ this . styles . header , ...AnimatedStyle1 . transform ] } >
324- < Image style = { imgStyle } source = { { uri : img } } />
248+ < Image style = { imgStyle } source = { imgSource } />
325249 </ Animated . View >
326250 < View style = { this . styles . info } >
327251 < Animated . View style = { AnimatedStyle2 . transform } >
@@ -361,6 +285,22 @@ export default class AppIntro extends Component {
361285 return animatedChild ;
362286 }
363287
288+ shadeStatusBarColor ( color , percent ) {
289+ const first = parseInt ( color . slice ( 1 ) , 16 ) ;
290+ const black = first & 0x0000FF ;
291+ const green = first >> 8 & 0x00FF ;
292+ const percentage = percent < 0 ? percent * - 1 : percent ;
293+ const red = first >> 16 ;
294+ const theme = percent < 0 ? 0 : 255 ;
295+ const finalColor = ( 0x1000000 + ( Math . round ( ( theme - red ) * percentage ) + red ) * 0x10000 + ( Math . round ( ( theme - green ) * percentage ) + green ) * 0x100 + ( Math . round ( ( theme - black ) * percentage ) + black ) ) . toString ( 16 ) . slice ( 1 ) ;
296+
297+ return `#${ finalColor } ` ;
298+ }
299+
300+ isToTintStatusBar ( ) {
301+ return this . props . pageArray && this . props . pageArray . length > 0 && Platform . OS === 'android'
302+ }
303+
364304 render ( ) {
365305 const childrens = this . props . children ;
366306 const { pageArray } = this . props ;
@@ -391,13 +331,23 @@ export default class AppIntro extends Component {
391331 } ) ;
392332 }
393333 }
334+
335+ if ( this . isToTintStatusBar ( ) ) {
336+ StatusBar . setBackgroundColor ( this . shadeStatusBarColor ( this . props . pageArray [ 0 ] . backgroundColor , - 0.3 ) , false ) ;
337+ }
338+
394339 return (
395340 < View >
396341 { androidPages }
397342 < Swiper
398343 loop = { false }
344+ index = { this . props . defaultIndex }
399345 renderPagination = { this . renderPagination }
400346 onMomentumScrollEnd = { ( e , state ) => {
347+ if ( this . isToTintStatusBar ( ) ) {
348+ StatusBar . setBackgroundColor ( this . shadeStatusBarColor ( this . props . pageArray [ state . index ] . backgroundColor , - 0.3 ) , false ) ;
349+ }
350+
401351 this . props . onSlideChange ( state . index , state . total ) ;
402352 } }
403353 onScroll = { Animated . event (
@@ -434,6 +384,10 @@ AppIntro.propTypes = {
434384 PropTypes . element ,
435385 ] ) ,
436386 customStyles : PropTypes . object ,
387+ defaultIndex : PropTypes . number ,
388+ showSkipButton : PropTypes . bool ,
389+ showDoneButton : PropTypes . bool ,
390+ showDots : PropTypes . bool ,
437391} ;
438392
439393AppIntro . defaultProps = {
@@ -449,4 +403,8 @@ AppIntro.defaultProps = {
449403 doneBtnLabel : 'Done' ,
450404 skipBtnLabel : 'Skip' ,
451405 nextBtnLabel : '›' ,
406+ defaultIndex : 0 ,
407+ showSkipButton : true ,
408+ showDoneButton : true ,
409+ showDots : true
452410} ;
0 commit comments