react-native结合react-navigation之TabNavigator

react

react-native开发需时肯定有tab的切换,或者页面的转调,当然用RN自身的Navigator 也可以但是也不是那么方便react-navigation

就能满足很多大部分需求,如下图的三种切换方式,下面就说下TabNavigator 和StackNavigator的应用,才踏的一个坑,还是太年轻呀,横刀一撸!!!!

主要的界面 用tab 切换即是TabNavigator, 切换如下图


一共四个页面当然配置就如下咯

// 两个参数 routeConfigs: NavigationRouteConfigMap,  config: TabNavigatorConfig = {}

// 一个route对应的页面和tab图标, 一个切换的样式整个tab栏的样式

//tab

export const AppNavigator = TabNavigator({

Hotshow: {screen: hotshow, navigationOptions: {

tabBarLabel: '热映',

tabBarIcon: ({ tintColor, focused }) => (

<Image resizeMode='contain'

source={require('../icon/icon_hot.png')}

style={[style.footImage, {tintColor: tintColor}]}

/>

)

}},

Usshow: {screen: usshow, navigationOptions: {

tabBarLabel: '北美',

tabBarIcon: ({ tintColor, focused }) => (

<Image style={[style.footImage, {tintColor: tintColor}]}

resizeMode='contain'

source={require('../icon/icon_us_normal.png')}

/>

)

}},

Soonshow: {screen: soonshow, navigationOptions: {

tabBarLabel: '近期',

tabBarIcon: ({ tintColor, focused }) => (

<Image style={[style.footImage, {tintColor: tintColor}]}

resizeMode='contain'

source={require('../icon/icon_soon_normal.png')}

/>

)}

},

Nearcinemas: {screen: nearcinemas, navigationOptions: {

tabBarLabel: '影院',

tabBarIcon: ({ tintColor, focused }) => (

<Image style={[style.footImage, {tintColor: tintColor}]}

resizeMode='contain'

source={require('../icon/icon_near_normal.png')}

/>

)},

}

}, {

tabBarPosition: 'bottom',

lazy: true, // 是否懒加载

initialRouteName: 'Hotshow',

tabBarOptions: {

showIcon: true,

pressOpacity: 0.8,

style: {

height: 45,

backgroundColor: '#ffffff',

zIndex: 0,

position: 'relative'

},

labelStyle: {

fontSize: 11,

paddingVertical: 0,

marginTop: -4

},

iconStyle: {

marginTop: -3

},

tabStyle: {

backgroundColor: 'rgb(230,69,51)',

},

}

});


TabNavigatorConfig更多具体的参数如下

/**

* Tab Navigator

*/

export interface TabNavigatorConfig {

tabBarComponent?: React.ReactElement<any>,

tabBarPosition?: 'top'|'bottom',

swipeEnabled?: boolean,

animationEnabled?: boolean,

lazy?: boolean,

tabBarOptions?: {

activeTintColor?: string,

activeBackgroundColor?: string,

inactiveTintColor?: string,

inactiveBackgroundColor?: string,

showLabel?: boolean,

style?: ViewStyle,

labelStyle?: TextStyle,

// Top

showIcon?: boolean,

upperCaseLabel?: boolean,

pressColor?: string,

pressOpacity?: number,

scrollEnabled?: boolean,

tabStyle?: ViewStyle,

indicatorStyle?: ViewStyle

}

initialRouteName?: string,

order?: string[],

paths?: any // TODO: better def

backBehavior?: 'initialRoute'|'none'

}

如上都配置好了,就需要在屏幕上显示 ,下面代码作为展示 主要的还是创建了AppWithNavigationState 然后export 出他, 在root下调用

class AppWithNavigationState extends Component {

render() {

return(

<View style={{flex: 1}}>

{this.props.fetchbool ? <Loading/> :

<AppNavigator navigation={

addNavigationHelpers({dispatch: this.props.navigator,

state: this.props.nav})

}/>

}

</View>

)

}

}

function mapStateToProeps(state){

return {

fetchbool: state.fetchload.data,

nav: state.nav

}

};

function macthDispatchToProps(dispatch) {

return bindActionCreators({

navigator: navigator,

initHotshowAction: initHotshow,

fetchLoading: fetchLoading

}, dispatch);

}

let style = StyleSheet.create({

footImage: {

width: 25,

height: 25

},

});

export default connect(mapStateToProeps, macthDispatchToProps)(AppWithNavigationState);

结合了redux , nav就是通过state 传递的,在redux目录下创建了一个navigators/reducer

import { NavigationActions } from 'react-navigation';

import { AppNavigator } from '../../navigators/AppNavigator';

const initialNavState = {

index: 0,

routes: [

{

key: 'Hotshow',

routeName:'Hotshow',

},

{

key: 'Usshow',

routeName:'Usshow',

},

{

key: 'Soonshow',

routeName:'Soonshow',

},

{

key: 'Nearcinemas',

routeName:'Nearcinemas',

},

],

};

export const nav = (state = initialNavState, action) => {

let nextState;

switch (action.type) {

case 'Usshow':

return AppNavigator.router.getStateForAction(

NavigationActions.navigate({ routeName: 'Usshow' }),

state

);

case 'Soonshow':

setate.index= 1

return AppNavigator.router.getStateForAction(

NavigationActions.navigate({ routeName: 'Soonshow' }),

state

);

case 'Nearcinemas':

return AppNavigator.router.getStateForAction(

NavigationActions.navigate({ routeName: 'Nearcinemas' }),

state

);

default:

//return AppNavigator.router.getStateForAction(action, state) || state;

// return AppNavigator.router.getStateForAction(

// state

// );

return AppNavigator.router.getStateForAction(

NavigationActions.navigate({ routeName: 'Hotshow' }),

state

) || state ;

}

}




做到此处,是个tab的四个页面切换还是可以的,问题就在与当我切换到下一个页面时,就出现了状况,


在没有做进入下一个页面前,提前ajax请求,当进入了请求,当然能请求成功,但是请求成功后,刚显示的界面会还在显示等待时,尼玛返回上一个界面

这么说有点拗口,不解其意


额,,,, 清洗脱俗,惊鸿一瞥下就给直接返回A了, console.log(this.props.nav)  看看了 输出一次 nav.index = 0 

然后 1 然后 0 ··········就这么又回到原点了,同时在AppWithNavigationState,解决办法想了一个在navigators/reducer里把nav传递的index固定了

export const nav = (state = initialNavState, action) => {

let nextState;

switch (action.type) {

case 'Usshow':

setate.index= 1

return AppNavigator.router.getStateForAction(

NavigationActions.navigate({ routeName: 'Usshow' }),

state

);

有次当然可以解决,但是 tab按钮不能点击咯,这真是尴尬的一幕,

当然还有个蛋疼的直接用TabNavigator 在AppWithNavigationState中的render 会运行四次,即第一个界面加载时,

console.log 输出变知道 当然这样也有办法解决,react 的生命周期呀,最前面的两个 实例化 和存在期,就在存在期入手,

shouldComponentUpdate(nextProps, nextState) {

return **** ? false : true ;

}

componentWillUpdate(nextProps, nextState) {

return *** ? false : true;

}

render()就减小了开销

问题是 tab还是不能点击啊!!!!!!!!

谜底是这样  StackNavigator 需要这个!!!!

export const StackNavigator = StackNavigator(

{

Tab:{screen: AppNavigator}, // 就是整个tab切换的 AppNavigator

Product:{screen: DtlWebView}

},

{

stackConfig:{

header: null,

headerBackTitle:null,

headerTintColor:'#333333',

showIcon:true,

swipeEnabled:false,

animationEnabled:false,

initialRouteName: 'Hotshow'

},

mode:'card',

}

);

stackConfig 主要参数

 TabNavigator, StackNavigator配合应用就很好区分开了前者模块页面之间,后者Stack由字面理解就是通过栈的方式进行切换,最新的就压入到栈顶显示

在App 里之前的就改为StackNavigator

class App extends Component {

render() {

return (

<Provider store={ store }>

<StackNavigator />

</Provider>

);

}

}

到此就结束咯




不对之处,敬请更正··········



react-native开发需时肯定有tab的切换,或者页面的转调,当然用RN自身的Navigator 也可以但是也不是那么方便react-navigation

就能满足很多大部分需求,如下图的三种切换方式,下面就说下TabNavigator 和StackNavigator的应用,才踏的一个坑,还是太年轻呀,横刀一撸!!!!

主要的界面 用tab 切换即是TabNavigator, 切换如下图


一共四个页面当然配置就如下咯

// 两个参数 routeConfigs: NavigationRouteConfigMap,  config: TabNavigatorConfig = {}

// 一个route对应的页面和tab图标, 一个切换的样式整个tab栏的样式

//tab

export const AppNavigator = TabNavigator({

Hotshow: {screen: hotshow, navigationOptions: {

tabBarLabel: '热映',

tabBarIcon: ({ tintColor, focused }) => (

<Image resizeMode='contain'

source={require('../icon/icon_hot.png')}

style={[style.footImage, {tintColor: tintColor}]}

/>

)

}},

Usshow: {screen: usshow, navigationOptions: {

tabBarLabel: '北美',

tabBarIcon: ({ tintColor, focused }) => (

<Image style={[style.footImage, {tintColor: tintColor}]}

resizeMode='contain'

source={require('../icon/icon_us_normal.png')}

/>

)

}},

Soonshow: {screen: soonshow, navigationOptions: {

tabBarLabel: '近期',

tabBarIcon: ({ tintColor, focused }) => (

<Image style={[style.footImage, {tintColor: tintColor}]}

resizeMode='contain'

source={require('../icon/icon_soon_normal.png')}

/>

)}

},

Nearcinemas: {screen: nearcinemas, navigationOptions: {

tabBarLabel: '影院',

tabBarIcon: ({ tintColor, focused }) => (

<Image style={[style.footImage, {tintColor: tintColor}]}

resizeMode='contain'

source={require('../icon/icon_near_normal.png')}

/>

)},

}

}, {

tabBarPosition: 'bottom',

lazy: true, // 是否懒加载

initialRouteName: 'Hotshow',

tabBarOptions: {

showIcon: true,

pressOpacity: 0.8,

style: {

height: 45,

backgroundColor: '#ffffff',

zIndex: 0,

position: 'relative'

},

labelStyle: {

fontSize: 11,

paddingVertical: 0,

marginTop: -4

},

iconStyle: {

marginTop: -3

},

tabStyle: {

backgroundColor: 'rgb(230,69,51)',

},

}

});


TabNavigatorConfig更多具体的参数如下

/**

* Tab Navigator

*/

export interface TabNavigatorConfig {

tabBarComponent?: React.ReactElement<any>,

tabBarPosition?: 'top'|'bottom',

swipeEnabled?: boolean,

animationEnabled?: boolean,

lazy?: boolean,

tabBarOptions?: {

activeTintColor?: string,

activeBackgroundColor?: string,

inactiveTintColor?: string,

inactiveBackgroundColor?: string,

showLabel?: boolean,

style?: ViewStyle,

labelStyle?: TextStyle,

// Top

showIcon?: boolean,

upperCaseLabel?: boolean,

pressColor?: string,

pressOpacity?: number,

scrollEnabled?: boolean,

tabStyle?: ViewStyle,

indicatorStyle?: ViewStyle

}

initialRouteName?: string,

order?: string[],

paths?: any // TODO: better def

backBehavior?: 'initialRoute'|'none'

}

如上都配置好了,就需要在屏幕上显示 ,下面代码作为展示 主要的还是创建了AppWithNavigationState 然后export 出他, 在root下调用

class AppWithNavigationState extends Component {

render() {

return(

<View style={{flex: 1}}>

{this.props.fetchbool ? <Loading/> :

<AppNavigator navigation={

addNavigationHelpers({dispatch: this.props.navigator,

state: this.props.nav})

}/>

}

</View>

)

}

}

function mapStateToProeps(state){

return {

fetchbool: state.fetchload.data,

nav: state.nav

}

};

function macthDispatchToProps(dispatch) {

return bindActionCreators({

navigator: navigator,

initHotshowAction: initHotshow,

fetchLoading: fetchLoading

}, dispatch);

}

let style = StyleSheet.create({

footImage: {

width: 25,

height: 25

},

});

export default connect(mapStateToProeps, macthDispatchToProps)(AppWithNavigationState);

结合了redux , nav就是通过state 传递的,在redux目录下创建了一个navigators/reducer

import { NavigationActions } from 'react-navigation';

import { AppNavigator } from '../../navigators/AppNavigator';

const initialNavState = {

index: 0,

routes: [

{

key: 'Hotshow',

routeName:'Hotshow',

},

{

key: 'Usshow',

routeName:'Usshow',

},

{

key: 'Soonshow',

routeName:'Soonshow',

},

{

key: 'Nearcinemas',

routeName:'Nearcinemas',

},

],

};

export const nav = (state = initialNavState, action) => {

let nextState;

switch (action.type) {

case 'Usshow':

return AppNavigator.router.getStateForAction(

NavigationActions.navigate({ routeName: 'Usshow' }),

state

);

case 'Soonshow':

setate.index= 1

return AppNavigator.router.getStateForAction(

NavigationActions.navigate({ routeName: 'Soonshow' }),

state

);

case 'Nearcinemas':

return AppNavigator.router.getStateForAction(

NavigationActions.navigate({ routeName: 'Nearcinemas' }),

state

);

default:

//return AppNavigator.router.getStateForAction(action, state) || state;

// return AppNavigator.router.getStateForAction(

// state

// );

return AppNavigator.router.getStateForAction(

NavigationActions.navigate({ routeName: 'Hotshow' }),

state

) || state ;

}

}




做到此处,是个tab的四个页面切换还是可以的,问题就在与当我切换到下一个页面时,就出现了状况,


在没有做进入下一个页面前,提前ajax请求,当进入了请求,当然能请求成功,但是请求成功后,刚显示的界面会还在显示等待时,尼玛返回上一个界面

这么说有点拗口,不解其意


额,,,, 清洗脱俗,惊鸿一瞥下就给直接返回A了, console.log(this.props.nav)  看看了 输出一次 nav.index = 0 

然后 1 然后 0 ··········就这么又回到原点了,同时在AppWithNavigationState,解决办法想了一个在navigators/reducer里把nav传递的index固定了

export const nav = (state = initialNavState, action) => {

let nextState;

switch (action.type) {

case 'Usshow':

setate.index= 1

return AppNavigator.router.getStateForAction(

NavigationActions.navigate({ routeName: 'Usshow' }),

state

);

有次当然可以解决,但是 tab按钮不能点击咯,这真是尴尬的一幕,

当然还有个蛋疼的直接用TabNavigator 在AppWithNavigationState中的render 会运行四次,即第一个界面加载时,

console.log 输出变知道 当然这样也有办法解决,react 的生命周期呀,最前面的两个 实例化 和存在期,就在存在期入手,

shouldComponentUpdate(nextProps, nextState) {

return **** ? false : true ;

}

componentWillUpdate(nextProps, nextState) {

return *** ? false : true;

}

render()就减小了开销

问题是 tab还是不能点击啊!!!!!!!!

谜底是这样  StackNavigator 需要这个!!!!

export const StackNavigator = StackNavigator(

{

Tab:{screen: AppNavigator}, // 就是整个tab切换的 AppNavigator

Product:{screen: DtlWebView}

},

{

stackConfig:{

header: null,

headerBackTitle:null,

headerTintColor:'#333333',

showIcon:true,

swipeEnabled:false,

animationEnabled:false,

initialRouteName: 'Hotshow'

},

mode:'card',

}

);

stackConfig 主要参数

 TabNavigator, StackNavigator配合应用就很好区分开了前者模块页面之间,后者Stack由字面理解就是通过栈的方式进行切换,最新的就压入到栈顶显示

在App 里之前的就改为StackNavigator

class App extends Component {

render() {

return (

<Provider store={ store }>

<StackNavigator />

</Provider>

);

}

}

到此就结束咯




不对之处,敬请更正··········



以上是 react-native结合react-navigation之TabNavigator 的全部内容, 来源链接: utcz.com/z/382048.html

回到顶部