React Native--使用React Navigation实现界面导航与跳转

        在浏览器中我们可以通过标签与url实现不同页面之间的跳转,利用浏览器的返回按钮返回之前浏览的页面,但是在React Native中却没有集成内嵌的全局栈来实现这个界面的跳转,因此需要使用第三方库来实现这个功能。React Navigation就是这样一个源于ReactNative社区的用于实现界面导航的js库。通过如下方法安装react navigation到你的项目中:

yarn add react-navigation
# 或者通过npm安装:
# npm install --save react-navigation

        React Navigation常用有三个组件,其中StackNavigator用于实现页面跳转,TabNavigation用于标签页之间切换,DrawerNavigation用于实现抽屉式侧边栏。使用前需要先引入组件:

import {DrawerNavigator,TabNavigator,StackNavigator} from 'react-navigation'

1、StackNavigator

        StackNavigator组件用于实现在不同的页面之间的跳转,并且对页面历史进行管理,就像浏览器那样,用一个栈保存浏览页面。当你打开一个新页面时,将页面压入栈顶,当你需要返回时,从栈顶弹出页面。不同的是,通过React Navigation可以在移动设备上获得更加真实的用户体验,比如利用屏幕手势操作,以及更加逼真的动画切换效果。

React Native--使用React Navigation实现界面导航与跳转_第1张图片

 1.1、定义路由

        总体上看StackNavigator()接收两个参数,分别是需要跳转管理的路由模块以及Navigator的基本设置,返回一个React Component组件。因此可以将你的所有页面作为路由模块放在StackNavigator中形成根路由RootStack,然后将其作为ReactNative的入口导出。

        在每个路由模块中通过screen关键字定义对应渲染的ReactNative组件

const RootStack = StackNavigator(
  {//定义路由
    Home: {                       //定义Home对应HomeScreen组件
      screen: HomeScreen,
    },
    Details: {
      screen: DetailsScreen,
    },
  },
  {//定义配置
    initialRouteName: 'Home',     //设置初始路由为Home
  }
);

export default class App extends Component {
  render() {                            //将Navigation作为根路径导出
    return <RootStack />;
  }
}

        嵌套路由:由于StackNavigator返回一个React组件,因此它也可以作为子组件添加到另一个StackNavigator路由中,形成层叠路由结构。例如Home Screen与DetailScreen构成MainStack,MainStack与ModalScreen构成RootStack:

React Native--使用React Navigation实现界面导航与跳转_第2张图片      React Native--使用React Navigation实现界面导航与跳转_第3张图片

1.2、路由跳转

        StackNavigator会为每个注册的路由组件传递参数navigation属性,通过this.props.navigationnavigate方法可以实现页面间的跳转,其参数为StackNavigator中已定义的路由,例如从主页跳转到详情页Details:

<Button title='跳转到详情' onPress={()=>this.props.navigation.navigate('Details')} />

        返回:每个界面的头部导航栏左边默认设置了一个返回按钮,通过它可以返回到之前一个页面,如果你希望手动触发返回,可以调用this.props.navigation.goBack()

        路由跳转实际上就是新打开一个页面并将路由压入一个栈中,点击返回时,从栈顶弹出一个页面。与浏览器不同的是,当给navigate传递的参数是本页面时,它依旧会压入栈内,点击返回时会弹出本页面,而浏览器会辨别这是本页面,不会再压入栈顶。

1.3、参数传递

        当页面跳转时,可以把需要传递的数据作为参数放在navigate方法的第二个参数中,例如:

<Button title='跳转到详情'
        onPress={()=>this.props.navigation.navigate('Details',{
          userName:'Tory',
          userInfo:'Hello'
        })}
/>
        在路由页面内,通过 this.props.navigation.state.params可以得到上一个页面传入的参数,例如在Details页面获取上面的数据:
class DetailsScreen extends Component {
  render() {
    const data=this.props.navigation.state.params;
    return (
      <View style={styles.container}>
        <Text>你好,{data.userName}!Text>
      View>
    );
  }
}

1.4、导航栏设置

       通过对组件内的静态常量 navigationOptions可以对组件的导航栏进行设置。
    1.4.1、设置与修改

        静态对象:navigationOptions可以直接接收一个对象,例如设置详情页导航栏的标题

class DetailsScreen extends Component {
  static navigationOptions = {
    title: '详情页'
  };
}
     函数返回:由于上面通过static设置的静态常量,它不是组件的一个实例,无法通过this.props访问到navigation.state.params。但如果通过函数的方式返回navigationOptions对象,React Navigation在调用函数时会函数默认传入参数props,就可以拿到params。例如:
static navigationOptions=((props)=>{
  return {
    title:props.navigation.state.params.title
  }
});

        修改navigationOptions:通过this.props.navigation.setParams()方法可以对params进行修改,例如修改标题:

<Button title='修改标题'
        onPress={()=>{
          this.props.navigation.setParams({title:'修改后的标题'})
        }}
/>
    1.4.2、navigationOptions属性
static navigationOptions={
  title:'详情页',
  header:HeaderComponent,                       //自定义头部组件
  headerTitle:TitleComponent,                   //自定义标题组件
  headerLeft:LeftComponent,                     //自定义左边组件,会替换掉默认返回按钮
  headerRight:<Text>右边元素Text>,            //自定义右边元素,注意这里不可以放组件
  headerBackImage:{uri:'mipmap/ic_launcher'},   //自定义返回按钮的图片
  headerStyle:{                                 //导航栏样式设置
    backgroundColor:'#8bc9ff',
  },
  headerTintColor:'#fff',                       //按钮、标题颜色设置
  headerTitleStyle:{                            //标题字体样式设置
    fontWeight:'bold',
  },
  headerTransparent:true,                       //使头部背景透明
  gesturesEnabled:true,                         //开启手势操作
  gestureDirection:'inverted',            //修改返回手势操作方向为从右到左,默认为从左到右
  gestureResponseDistance:{               //定义手势响应距离屏幕边界的距离
    horizontal:100,
    vertical:50
  }
};

       如果在组件内部定义navigationOptions,它只会对当前页面起作用,如果希望对所有组件设置通用options,可以把navigationOptions对象放在前面的1.1提到的路由定义中。页面内的navigationOptions比通用设置具有更高的优先级。

        注意自定义组件返回的是JSX元素,而不是React Component类。

const RootStack = StackNavigator(
  {//定义路由
    Home: {screen: HomeScreen},
    Details:{screen: DetailsScreen},
  },
  {//定义配置
    initialRouteName: 'Home',     
    navigationOptions:{           //导航栏通用设置
      headerStyle:{
        backgroundColor:'#7276ff'
      }
    }
  }
);

1.5、头部与组件通信

        在navigationOptions中设置的组件无法通过this访问到页面组件DetailsScreen,如果希望二者之间进行通信,则需要借助navigation.params。例如:

class DetailsScreen extends React.Component {
  state={count:0};
  static navigationOptions = (props) => {
    const params = props.navigation.state.params;
    return {
      headerRight: (                        //通过params为按钮绑定increase方法
        <Button onPress={params.increase} title="+1" />
      ),
    };
  };

  componentWillMount() {                    //通过setParams将increase方法绑定到_increase
    this.props.navigation.setParams({ increase: this._increase });
  }
  _increase=()=>{                           //设置state.count+1
    this.setState(preState=>{return {count:preState.count+1}});
  };
  render() {
    return (
      <View style={styles.container}>
        <Text>计数为:{this.state.count}Text>
      View>
    );
  }
}
        在navigationOptions中的

你可能感兴趣的:(WEB)