React Native经常使用组件之TabBarIOS、TabBarIOS.Item组件、Navigator组件、NavigatorIOS组件、React Navigation第三方

如下内容为老版本React Native,faceBook已经有了新的导航组件,请移步其余博客参考>>我是传送门

参考资料:React Navigationhtml

 react-native-tab-navigator的使用传送门node

TabBarIOS部分   

  在目前市面上的APP中,大部分都是选项与选项之间的切换,好比:微信、微博、QQ空间......, 在iOS中,咱们能够经过TabItem类进行实现。那么,在React Native中,咱们应该怎么实现呢?react

   在React Native中能够经过TabBarIOS和TabBarIOS.Item组件来实现选项卡切换效果,你们能够看到后面带有IOS,因此这个组件是不支持Android的,固然后面咱们能够自定义该组件。ios

1、TabBarIOS常见的属性git

View的全部属性均可以被继承github

barTintColor  color  设置tab条的背景颜色npm

tintColor color  设置tab条上被选中图标的颜色json

translucent  bool   设置Tab栏是否是半透明的效果react-native

2、TabBarIOS.Item常见的属性数组

badge   number  

  在图标的右上方显示小红色气泡,显示信息

icon  Image.propTypes.source    

  Tab按钮自定义的图标,若是systemicon属性被定义了,那么该属性会被忽略

onPress  function   

  当Tab按钮被选中的时候进行回调,你能够设置selected={true}来设置组件被选中

selected  bool    

       该属性标志子页面是否可见,若是是一个空白的内容页面,那么必定是忘记了选中任何的一个页面标签Tab

selectedIcon   Image.propTypes.source   

       设置当Tab按钮被选中的时候显示的自定义图标,若是systemIcon属性被设置了,那么该属性会被忽略。若是定义了icon属性,可是当前的selectedIcon属性没有设置,那么该图标会被设置成蓝色

style     设置样式风格,继承View的样式各类风格

systemIcon  

  enum('bookmarks','contacts','downloads','favorites','featured','history','more','most-recent','most-viewed','recents','search','top-rated')

        系统预约义的图标,若是你使用这些图标,那么你上面设置的标题,选中的图标都会被这些系统图标所覆盖。

 title   string    

       在Tab按钮图标下面显示的标题信息,若是你设置了SystemIcon属性,那么该属性会被忽略

3、TabBarIOS.Item案例展现

  代码展现:

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */

import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  Image,
  TabBarIOS
} from 'react-native';

var Car = require('./Car.json');

export default class FListViewDemo1 extends Component{
  constructor(props){
    super(props);
    this.state = {
      selectedTabBarItem:'home'
    };
  }
  render(){
    return(
      <View style={styles.container}>

        <View style={styles.headerViewStyle}>
           <Text style={{color:'white'}}>Tab选项卡切换</Text>
        </View>

        <TabBarIOS barTintColor='white'>

            <TabBarIOS.Item systemIcon="contacts"
                            badge="3"
                            // title="张三"
                            selected={this.state.selectedTabBarItem == 'home'}
                            onPress ={()=>{this.setState({selectedTabBarItem:'home'})}}
            >
              <View style={[styles.commentViewStyle,{backgroundColor:'red'}]}>
                  <Text>首页</Text>
              </View>
            </TabBarIOS.Item>

            <TabBarIOS.Item systemIcon="bookmarks"
                            // title="李四"
                            selected={this.state.selectedTabBarItem == 'second'}
                            onPress ={()=>{this.setState({selectedTabBarItem:'second'})}}
            >
                <View style={[styles.commentViewStyle,{backgroundColor:'green'}]}>
                    <Text>第二页</Text>
                </View>
            </TabBarIOS.Item>

            <TabBarIOS.Item systemIcon="contacts"
                            // title="王二"
                            selected={this.state.selectedTabBarItem == 'third'}
                            onPress ={()=>{this.setState({selectedTabBarItem:'third'})}}
            >
              <View style={[styles.commentViewStyle,{backgroundColor:'blue'}]}>
                  <Text>第三页</Text>
              </View>
            </TabBarIOS.Item>

            <TabBarIOS.Item systemIcon="contacts"
                            // title ="麻子"
                            selected={this.state.selectedTabBarItem == 'four'}
                            onPress ={()=>{this.setState({selectedTabBarItem:'four'})}}
            >
              <View style={[styles.commentViewStyle,{backgroundColor:'purple'}]}>
                  <Text>第四页</Text>
              </View>
            </TabBarIOS.Item>
        </TabBarIOS>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  headerViewStyle:{
    height:64,
    backgroundColor:'black',
    justifyContent:'center',
    alignItems:'center'
  },
  commentViewStyle:{
    flex:1,
    alignItems:'center',
    justifyContent:'center'
  },
  container:{
    flex:1,
    backgroundColor:'#f5fcff'
  }
});

  提示:在TabBarIOS.Item中,若是设置了systemIcon,再去设置title将不会起做用。

 


 

Navigator部分

  在开发中,咱们须要实现多个界面的切换,这时候就须要一个导航控制器来进行各类效果的切换。那么,在React Native中有两个组件可以实现这样的效果:Navigator和NavigatorIOS。

       其中Navigator是适配Android和iOS,而NavigatorIOS则是包装了UIKit的导航功能,可使用左划功能来返回到上一界面。

  提示:报错:'Navigator is deprecated and has been removed from this package. It can now be installed ' +

           'and imported from `react-native-deprecated-custom-components` instead of `react-native`. ' +
          'Learn about alternative navigation solutions at http://facebook.github.io/react-native/docs/navigation.html'

  这是由于版本升级到0.43以上的话,Navigator不能直接从react-native里面获取了,

  解决方案:

    npm install react-native-deprecated-custom-components --save

  而后在引用的地方

    import {Navigator} from 'react-native-deprecated-custom-components'

1、Navigator

       不少时候,咱们须要导航器来应对不一样场景(页面)间的切换。它经过路由对象来分辨不一样的场景,咱们这里采用的就是 renderScene 方法,根据指定的路由来渲染。

1.1 经常使用的属性

 initialRoute ={{ name: 'home', component: HomeScene }} 

   这个指定了默认的页面,也就是启动的组件页面

   configureScene ={() => {

    return Navigator. SceneConfigs .HorizontalSwipeJump;

  }}

  页面之间跳转时候的动画手势,能够看这个目录:node_modules/react-native/Libraries/CustomComponents/Navigator/NavigatorSceneConfigs.js(能够看其余跳转的时候的方向),好比:PushFromRight   FloatFromRight  FloatFromLeft   FloatFromBottom   FloatFromBottomAndroid    FadeAndroid   HorizontalSwipeJump    HorizontalSwipeJumpFromRight    VerticalUpSwipeJump    VerticalDownSwipeJump等等。

 renderScene 

        具体是方法以下:(route, navigator) =><MySceneComponent title={route.title} navigator={navigator} />      

       两个参数中的route包含的是initial的时候传递的name和component,而navigator是一个咱们须要用的Navigator的对象;

       因此当咱们拿到route中的component的时候,咱们就能够将navigator传递给它,正由于如此,咱们的组件HomeScene才能够经过  this.props.navigator,拿到路由。

 

initialRouteStack  [object] 参数对象数组   

       这是一个初始化的路由数组进行初始化。若是initalRoute属性没有设置的话,那么就必须设置initialRouteStack属性,使用该最后一项做为初始路由。 若是initalRouteStack属性没有设置的话,该会生成只包含initalRoute值的数组

 

navigationBar  node  

该为可选的参数,在页面切换中用来提供一个导航栏

 

navigator object   

该为可选参数,能够从父类导航器中获取导航器对象

 

sceneStyle 样式风格

该继承了View视图的全部样式风格,用于设置每一个页面容器的风格


1.2 经常使用的导航器方法

 

      当获取了导航器对象的引用,咱们能够进行调用如下一些方法来实现页面导航功能:

getCurrentRoutes()    该进行返回存在的路由列表信息

jumpBack()    该进行回退操做  可是该不会卸载(删除)当前的页面

jumpForward()    进行跳转到至关于当前页面的下一个页面

jumpTo(route)    根据传入的一个路由信息,跳转到一个指定的页面(该页面不会卸载删除)

push(route)     导航切换到一个新的页面中,新的页面进行压入栈。经过jumpForward()方法能够回退过去

pop()   当前页面弹出来,跳转到栈中下一个页面,而且卸载删除掉当前的页面

replace(route)   只用传入的路由的指定页面进行替换掉当前的页面

replaceAtIndex(route,index)     传入路由以及位置索引,使用该路由指定的页面跳转到指定位置的页面

replacePrevious(route)    传入路由,经过指定路由的页面替换掉前一个页面

resetTo(route)  进行导航到新的界面,而且重置整个路由栈

immediatelyResetRouteStack(routeStack)   该经过一个路由页面数组来进行重置路由栈

popToRoute(route)   进行弹出相关页面,跳转到指定路由的页面,弹出来的页面会被卸载删除

popToTop()  进行弹出页面,导航到栈中的第一个页面,弹出来的全部页面会被卸载删除

1.3 默认写法

<Navigator
    initialRoute={{ name: defaultName, component: defaultComponent }}
    configureScene={(route) => {
        return Navigator.SceneConfigs.HorizontalSwipeJumpFromRight;
    }}
    renderScene={(route, navigator) => {
        let Component = route.component;
        return <Component {...route.props} navigator={navigator} />
    }}
/>

2、Navigator.IOS

       NavigatorIOS包装了UIKit的导航功能,可使用左划功能来返回到上一界面。

2.1  经常使用的导航器方法

  • push(route) 

  • 导航器跳转到一个新的路由。

  •  

  • pop() 

  • 回到上一页。

  •  

  • popN(n) 

  • 回到N页以前。当N=1的时候,效果和 pop() 同样。

  •  

  • replace(route) 

  • 替换当前页的路由,并当即加载新路由的视图。

  •  

  • replacePrevious(route) 

  • 替换上一页的路由/视图。

  •  

  • replacePreviousAndPop(route) 

  • 替换上一页的路由/视图而且马上切换回上一页。

  •  

  • resetTo(route) 

  • 替换最顶级的路由而且回到它。

  •  

  • popToRoute(route)

  •  一直回到某个指定的路由。

  •  

  • popToTop() 

  • 回到最顶层的路由。

 

2.2  经常使用的属性

barTintColor string 

导航条的背景颜色。

  initialRoute {

  component: function,   // 路由到对应的版块

  title: string,   // 标题

  passProps: object,   // 传递的参数

  backButtonIcon: Image.propTypes.source,  // 返回按钮

  backButtonTitle: string,  // 返回按钮标题

  leftButtonIcon:Image.propTypes.source,  

  leftButtonTitle: string, 

  onLeftButtonPress: function, 

  rightButtonIcon: Image.propTypes.source, 

  rightButtonTitle: string, 

  onRightButtonPress: function, 

  wrapperStyle: [object Object]

       NavigatorIOS使用"路由"对象来包含要渲染的子视图、它们的属性、以及导航条配置。"push"和任何其它的导航函数的参数都是这样的路由对象。

       好比:下面新闻列表跳转到新闻详情页详情页: 

 itemWrapperStyle View#style

      导航器中的组件的默认属性。一个常见的用途是设置全部页面的背景颜色。

navigationBarHidden  bool 

  一个布尔值,决定导航栏是否隐藏。

shadowHidden bool 

  一个布尔值,决定是否要隐藏1像素的阴影。

tintColor string 

  导航栏上按钮的颜色。

 titleTextColor string 

  导航器标题的文字颜色。

translucent bool 

  一个布尔值,决定是否导航条是半透明的。

 

3、综合小案例

  3.1 部分核心代码

 

 


React Navigation部分

  React Navigation 源于 React Native 社区对一个可扩展且易于使用的导航解决方案的需求,它彻底使用 JavaScript 编写(所以你能够阅读并理解全部源码)。

安装

  在你的 React Native 项目中安装react-navigation这个包

yarn add react-navigation
# or with npm # npm install --save react-navigation

  而后,安装 react-native-gesture-handler。 若是你使用 Expo,就什么都不须要作,他已经包含在 SDK 中 了, 不然:

yarn add react-native-gesture-handler
# or with npm # npm install --save react-native-gesture-handler

  Link 全部的原生依赖

react-native link react-native-gesture-handler

使用指南

  官方文档:https://reactnavigation.org/docs/zh-Hans/getting-started.html

实例代码:

// In App.js in a new project
import React,{Component} from "react";
import {
  View,
  Text,
  Button,
  Image
} from "react-native";
import { createStackNavigator, createAppContainer } from "react-navigation";

//使用自定义组件替换标题
class LogoTitle extends Component{
  render(){
    return(
      <Image
        source={require('./img/img_02.png')}
        style={{width:30,height:30}}
      />
    );
  }
}
class ThreeScreen extends Component{

  static navigationOptions ={
    title:'ThreeScreen'
  };
  render(){
    return(
      <View style={{flex:1,alignItems:'center',justifyContent:'center'}}>
        <Text>ThressScreen</Text>

      </View>
    );
  }
}
class DetailsScreen extends Component{
  static navigationOptions=({navigation})=>{
    return{
      title:navigation.getParam('otherParam','A Nested Details Screen')
    };
  };
  render(){
    const {navigation} = this.props;
    const itemId = navigation.getParam('itemId','NO-ID');
    const otherParam = navigation.getParam('otherParam','some default value');
    return(
      <View style={{flex:1,alignItems:'center',justifyContent:'center'}}>
        <Text>DetailsScreen</Text>
        <Text>itemId:{JSON.stringify(itemId)}</Text>
        <Text>otherParam:{JSON.stringify(otherParam)}</Text>
        <Button
          title="Go to Details... again"
          onPress={()=>this.props.navigation.navigate('Three',{
              itemId:Math.floor(Math.random()*100)
            })
          }
        />
        <Button
          title="Update the title"
          onPress={()=>this.props.navigation.setParams({otherParam:'Update!'})}
        />
      </View>
    );
  }
}

class HomeScreen extends Component {
  static navigationOptions={
    headerTitle:<LogoTitle/>,
    headerRight:(
      <Button
        onPress={()=>alert('this is a button!')}
        title = "info"
        color ="#fff"
      />
    ),
  };
  render() {
    return (
       <View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
        <Text>Home Screen</Text>
        <Button
          title="Go to Details"
          onPress={()=>{this.props.navigation.navigate('Details',{
            itemId:86,
            otherParam:'anything you want here'
          });
        }}
        />
      </View>
    );
  }
}
const AppNavigator = createStackNavigator(
  {
    Home:HomeScreen,
    Details:DetailsScreen,
    Three:ThreeScreen

  },
  {
    initialRouteName:"Home",
    defaultNavigationOptions:{
      headerStyle:{
        backgroundColor:'#fdd000'
      },
      headerTintColor:'#fff',
      headerTitleStyle:{
        fontWeight:'bold'
      }
    }
  }
);

export default createAppContainer(AppNavigator);
View Code
import React,{Component} from 'react';
import { Text, View,Button,AppRegistry,StyleSheet,Image} from 'react-native';
import Ionicons from 'react-native-vector-icons/Ionicons';
import {
  createBottomTabNavigator,
  createStackNavigator,
  createAppContainer,
} from 'react-navigation';

class FiveScreen extends Component{
  static navigationOptions={
    title:'FiveScreen',
    headerBackTitle:null
  };
  render() {
    return (
      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
        <Text>FiveScreen!</Text>
      </View>
    );
  }
}

class FourScreen extends Component{
  static navigationOptions={
    title:'FourScreen',
    headerBackTitle:null
  };
  render() {
    return (
      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
        <Text>FourScreen!</Text>
      </View>
    );
  }
}
class DetailsScreen extends React.Component {
  static navigationOptions={
    title:'DetailsScreen',
    headerBackTitle:null
  };
  render() {
    return (
      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
        <Text>Details!</Text>
        <Button
          title = "Go to FourScreen"
          onPress={()=>this.props.navigation.navigate('Four')}
        />
      </View>
    );
  }
}

class HomeScreen extends React.Component {
  static navigationOptions={
    title:'HomeScreen',
    headerBackTitle:null,
    headerRight:(
      <Button
        title = "info"
        color = 'black'
        onPress = {()=>this.props.navigation.navigate('Five')}
      />
    )
  };
  render() {
    return (
      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
        {/* other code from before here */}
        <Button
          title="Go to Details"
          onPress={() => this.props.navigation.navigate('Details')}
        />
      </View>
    );
  }
}

class SettingsScreen extends React.Component {
  static navigationOptions = {
    headerBackTitle:null,
    title:'SettingsScreen'
  };
  render() {
    return (
      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
        {/* other code from before here */}
        <Button
          title="Go to Details"
          onPress={() => this.props.navigation.navigate('Details')}
        />
      </View>
    );
  }
}

const HomeStack = createStackNavigator(
  {
    Home: HomeScreen,
    Details: DetailsScreen,
    Four:FourScreen,
    Five:FiveScreen
  },
  {
    defaultNavigationOptions:{
      headerStyle:{
        backgroundColor:'#fdd000',
      },
      headerTintColor:'#fff',
      headerTitleColor:{
        fontWeight:'bold'
      }
    }
  }
);

const SettingsStack = createStackNavigator(
  {
    Settings:{
      screen:SettingsScreen,
    } ,
    Details: DetailsScreen,
  },
  {
    defaultNavigationOptions:{
      headerStyle:{
        backgroundColor:'#fdd000',
      },
      headerTintColor:'#fff',
      headerTitleColor:{
        fontWeight:'bold'
      }
    }
  }
);


HomeStack.navigationOptions = ({ navigation }) => {

  let tabBarVisible = true;
  if (navigation.state.index > 0) {
    tabBarVisible = false;
  }
  return {
    tabBarVisible,

  };
};
SettingsStack.navigationOptions = ({ navigation }) => {

  let tabBarVisible = true;
  if (navigation.state.index > 0) {
    tabBarVisible = false;
  }
  return {
    tabBarVisible,
  };
};
export default createAppContainer(createBottomTabNavigator(
  {
    Home: {
      screen:HomeStack,
      navigationOptions: {
          tabBarLabel: '首页', // tabBar显示的文字
          tabBarIcon: ({tintColor}) => ( // tabBar显示的图标
              // 这里使用了react-native-vector-icons, 不熟悉的请看上方链接
              <Ionicons
                  name={'ios-add'}
                  size={30}
                  color={tintColor}
              />
          )
        }
    },
    Settings: {
      screen:SettingsStack,
      navigationOptions: {
          tabBarLabel: '设置', // tabBar显示的文字
          tabBarIcon: ({tintColor}) => ( // tabBar显示的图标
              // 这里使用了react-native-vector-icons, 不熟悉的请看上方链接
              <Ionicons
                  name={'ios-close'}
                  size={30}
                  color={tintColor}
              />
          )
        }
    },
  },
  {
    tabBarOptions: {
      activeTintColor: '#fdd000',
    }
  }
));

const styles = StyleSheet.create({
   tabBarIconStyle: {
      width: 30,
      height: 30,
   },
});
View Code
相关文章
相关标签/搜索