美文网首页
ReactNative组件介绍

ReactNative组件介绍

作者: 寒桥 | 来源:发表于2017-06-30 17:08 被阅读103次

    ReactNative组件介绍

    View组件
    Text组件
    TouchableOpacity组件
    TextInput组件
    Image组件
    ScrollView组件
    长列表FlatList或是SectionList组件
    ListView组件
    Navigator组件
    TabBarIOS组件

    View组件

    在Web开发中,div是最重要的一个元素,是页面布局的基础
    在ReactNative开发中,View组件的作用类似于div,是最基本的组件,被看作是容器组件

    import React, { Component } from 'react';
    import {
      AppRegistry,
      StyleSheet,
      Text,
      View
    } from 'react-native';
    
    var Demo = React.createClass({
      render: function () {
        return (
          <View style={[styles.container, styles.flex]}>
            <View style={styles.bgview}>
              <View style={[styles.flex, styles.center]}>
                <Text>酒店</Text>
              </View>
              <View style={[styles.flex, styles.lineLeftRight]}>
                <View style={[styles.flex, styles.center, styles.lineCenter]}>
                  <Text>海外酒店</Text>
                </View>
                <View style={[styles.flex, styles.center]}>
                  <Text>特价酒店</Text>
                </View>
              </View>
              <View style={styles.flex}>
                <View style={[styles.flex, styles.center, styles.lineCenter]}>
                  <Text>团购</Text>
                </View>
                <View style={[styles.flex, styles.center]}>
                  <Text>民宿·酒店</Text>
                </View>
              </View>
            </View>
          </View>
        );
      }
    });
    
    const styles = StyleSheet.create({
      container: {
        marginTop: 30,
        backgroundColor: "#F2F2F2",
      },
      // 多个子组件都需要设置
      flex: {
        flex: 1
      },
      // 多个组件需要设置
      center: {
        justifyContent: "center",
        alignItems: "center",
      },
      bgview: {
        flexDirection: "row",
        backgroundColor: "#FF607C",
        marginTop: 5,
        marginLeft: 5,
        marginRight: 5,
        height: 80,
        borderRadius: 5
      },
    
      // 给中间的区域设置左右边框
      lineLeftRight: {
        borderLeftWidth: 1,
        borderRightWidth: 1,
        borderColor: "white"
      },
    
      // 给上半区域设置下边框
      lineCenter: {
        borderBottomWidth: 1,
        borderBottomColor: "white"
      },
    });
    
    AppRegistry.registerComponent('Demo', () => Demo);
    

    运行结果:

    View组件示例效果.png

    Text组件

    常用特性:手指触摸事件
    numberOfLines 显示多少行
    可以设置字体颜色、大小、对齐方式等

    /*
      分析:
      界面布局分为两部分:Header和页面信息
      整个页面是一个组件,由两个子组件组成
    
      将组建分别写在单独的文件中,使用Module.exports将组件导出为独立的模块,
      可以在其他文件中使用
    */
    
    // 引入Header组件
    var Header = require("./header");
    var News = require("./news");
    
    var Demo = React.createClass({
      render: function () {
        // 定义一个数组
        var news = [
          "1.李克强在辽宁考察强调:狠抓改革创新",
          "2.美国西部发生27处山火 火势或加剧居民匆忙撤离美国西部发生27处山火 火势或加剧居民匆忙撤离",
          "3.运营团队为关注编"悬赏580万寻子"谣言 6人被抓",
          "4.男子称癫痫发作跌入地铁轨道受伤 起诉地铁索赔"
        ];
        return (
          <View style={styles.flex}>
            {/* Header */}
            <Header></Header>
            {/* News */}
            <News news={news}></News>
          </View>
        );
      }
    });
    
    const styles = StyleSheet.create({
      flex: {
        flex: 1,
      },
    });
    

    Header组件

    // 组件
    var Header = React.createClass({
      render: function () {
        return(
          <View style={styles.flex}>
            <Text style={styles.font}>
              <Text style={styles.font_1}>网易</Text>
              <Text style={styles.font_2}>新闻</Text>
              <Text>有态度</Text>
            </Text>
          </View>
        );
      }
    });
    
    // 样式
    var styles = StyleSheet.create({
      flex: {
        marginTop: 25,
        height: 40,
        borderBottomWidth: 1,
        borderBottomColor: "#EF2D36",
        alignItems: "center"
      },
      // 字体设置公共部分
      font: {
        fontSize: 25,
        fontWeight: "bold",
        textAlign: "center"
      },
      font_1: {
        color: "#CD1D1C",
      },
      font_2: {
        color: "#FFF",
        backgroundColor: "#CD1D1C"
      },
    });
    
    // 导出模块
    module.exports = Header;
    

    News组件

    // 组件
    var News = React.createClass({
      show: function (title) {
        alert(title);
      },
      render: function () {
        // 定义数组,用于存储Text组件
        var newsComponents = [];
        // 遍历存储信息的数组,从外界传入
        for (var i in this.props.news) {
          var text = (
            <Text
              onPress = {this.show.bind(this, this.props.news[i])}
              style={styles.news_item}
              numberOfLines={2}
              key={i}>
              {this.props.news[i]}
            </Text>
          )
          // 将设置号的Text存入数组
          newsComponents.push(text);
        }
        return(
          <View style={styles.flex}>
            <Text style={styles.news_title}>今日要闻</Text>
            {newsComponents}
          </View>
        );
      }
    });
    
    // 样式
    var styles = StyleSheet.create({
      flex: {
        flex: 1
      },
      // "今日要闻标题"
      news_title: {
        fontSize: 20,
        fontWeight: "bold",
        color: "#CD1D1C",
        marginLeft: 10,
        marginTop: 15
      },
      // 每条新闻
      news_item: {
        marginTop: 10,
        marginLeft: 10,
        marginRight: 10,
        fontSize: 15,
        lineHeight: 30,
      },
    
    });
    
    // 导出
    module.exports = News;
    

    运行效果:

    Text组件示例效果.png

    TouchableOpacity组件

    React Native 提供3个组件用于给其他没有触摸事件的组件绑定触摸事件

    • TouchableOpacity 透明触摸,点击时,组件会出现透明过渡效果
    • TouchableHighlight 高亮触摸,点击时,组件会出现高亮效果
    • TouchableWithoutFeedback 无反馈性触摸,点击时,组件无视觉变化
      注意: 需要导入组件

    TextInput组件

    TextInput是一个允许用户在应用中通过键盘输入文本的基本组件,本组件的属性提供了多种特性的配置,如自动完成,自动大小写,占位文字,以及多种不同的键盘类型(如纯数字键盘)等等

    常用的属性有:

    • placeholder: 占位符
    • value: 输入框的值
    • password 是否密文输入
    • returnKeyType: 键盘return键类型
    • onChangeText: 当文本变化时调用
    • onEndEditing: 当结束编辑时调用
    • onSubmitEditing: 当结束编辑,点击提交按钮时调用

    示例1

    class TextInputDemo extends Component {
      constructor(props) {
        super(props);
        this.state = {text: ""};
      }
    
      render() {
        return (
          <View style={{marginTop: 50, marginLeft: 15, marginRight: 15}}>
            <TextInput
              style={{height: 40, borderColor: "#CCC", borderWidth: 1, padding: 10}}
              placeholder="请输入..."
              onChangeText={(text) => this.setState({text})}
            />
            <Text style={{margin: 15}}>{this.state.text}</Text>
          </View>
        );
      }
    }
    
    module.exports = TextInputDemo;
    

    运行效果:

    运行效果.png

    示例2

    import React, { Component } from 'react';
    import {
      AppRegistry,
      StyleSheet,
      Text,
      View,
      TouchableOpacity,
      TextInput,
    } from 'react-native';
    
    /*
      React Native 提供3个组件用于给其他没有触摸事件的组件绑定触摸事件
      TouchableOpacity 透明触摸,点击时,组件会出现透明过渡效果
      TouchableHighlight 高亮触摸,点击时,组件会出现高亮效果
      TouchableWithoutFeedback 无反馈性触摸,点击时,组件无视觉变化
      需要导入组件
    
      TextInput是一个允许用户在应用中通过键盘输入文本的基本组件,本组件的属性提供了多种特性的配置,
      如自动完成,自动大小写,占位文字,以及多种不同的键盘类型(如纯数字键盘)等等
      常用的属性有:
      placeholder: 占位符    value: 输入框的值   password 是否密文输入
      returnKeyType: 键盘return键类型  onChangeText: 当文本变化时调用
      onEndEditing: 当结束编辑时调用
      onSubmitEditing: 当结束编辑,点击提交按钮时调用
    */
    var Search = React.createClass({
      getInitialState: function () {
        return {
          inputText: " "
        };
      },
      // 输入框的onChange实现
      getContent: function (text) {
        this.setState({
          inputText: text
        });
      },
      clickBtn: function () {
        alert(this.state.inputText);
      },
      render: function () {
        return (
          <View style={styles.container}>
            <View style={styles.flex}>
              <TextInput style={styles.input} returnKeyType="search" placeholder="请输入内容"
              onChangeText={this.getContent} onSubmitEditing={this.clickBtn}/>
            </View>
            <TouchableOpacity style={styles.btn} onPress={this.clickBtn}>
              <Text style={styles.search}>搜索</Text>
            </TouchableOpacity>
          </View>
        );
      }
    });
    
    var styles = StyleSheet.create({
      container: {
        flexDirection: "row",
        height: 45,
        marginTop: 25,
      },
      flex: {
        flex: 1,
      },
      input: {
        height: 45,
        borderWidth: 1,
        marginLeft: 5,
        paddingLeft: 5,
        borderColor: "#CCC",
        borderRadius: 4
      },
      btn: {
        width: 55,
        marginLeft: 5,
        marginRight: 5,
        backgroundColor: "#23BEFF",
        height: 45,
        justifyContent: "center",
        alignItems: "center",
      },
      search: {
        color: "#FFF",
        fontSize: 15,
        fontWeight: "bold"
      }
    });
    
    module.exports = Search;
    

    代码示例


    代码示例.jpg

    Image组件

    用于显示图片的组件,包括网络图片、静态资源等
    常用属性:

    • resizeMode: 图片适应模式cover、contain、stretch
    • source: 图片引用地址
    • iOS支持的属性: onLoad、onLoadEnd、onLoadStart、onProgress

    示例1:

    var ImageDemo = React.createClass({
      render: function () {
        return (
          <View style={styles.container}>
            <View style={styles.net}>
              <Image style={styles.netImage}
              source={{uri:"http://img0.imgtn.bdimg.com/it/u=1457625323,1263791389&fm=26&gp=0.jpg"}} />
            </View>
            <View style={styles.local}>
              <Image style={styles.localImage} source={require("image!logo")} />
            </View>
          </View>
        );
      }
    });
    
    var styles = StyleSheet.create({
      container: {
        flex: 1,
        margin: 25,
        alignItems: "center"
      },
      net: {
        marginTop: 30,
        width: 300,
        height: 200,
        justifyContent: "center",
        alignItems: "center",
        backgroundColor: "cyan"
      },
      netImage: {
        width: 280,
        height: 200,
        backgroundColor: "gray",
      },
      local: {
        marginTop: 30,
        width: 300,
        height: 200,
        justifyContent: "center",
        alignItems: "center",
        backgroundColor: "yellow"
      },
      localImage: {
        width: 180,
        height: 200,
        backgroundColor: "gray"
      }
    });
    

    示例2:

    import React, { Component } from 'react';
    import {
      AppRegistry,
      StyleSheet,
      Text,
      View,
      Image
    } from 'react-native';
    
    // 导入json数据
    var bagsData = require("./data.json");
    console.log(bagsData.data);
    
    // 定义一些全局的
    var Dimensions = require('Dimensions');
    var {width} = Dimensions.get("window");
    var col = 3;
    var boxW = 100;
    var boxH = 120;
    var vMargin = (width - col * boxW) / (col + 1);
    var hMargin = 25;
    
    var ShowImage = React.createClass({
      renderAllImages: function () {
        var allBag = [];
        for (var i = 0; i < bagsData.data.length; i++) {
          var bag = bagsData.data[i];
          var bagData = (
            <View key={i} style={styles.outViewStyle}>
              <Image source={require('./img/danjianbao.jpg')} style={styles.imagesStyle}/>
              <Text style={styles.mainTitleStyle}>{bag.title}</Text>
            </View>
          );
          allBag.push(bagData);
        }
        return allBag;
      },
      render: function () {
        return (
          <View style={styles.container}>
            {
              this.renderAllImages()
            }
          </View>
        );
      }
    });
    
    var styles = StyleSheet.create({
        container: {
          flexDirection: "row",
          flexWrap: "wrap",
          backgroundColor: "lightgreen",
          marginTop: 30
        },
        outViewStyle: {
          alignItems: "center",
          width: boxW,
          height: boxH,
          marginLeft: vMargin,
          marginTop: hMargin
        },
        imagesStyle: {
          width: 80,
          height: 80
        },
        mainTitleStyle: {
          marginTop: 10,
          fontSize: 18
        },
    });
    
    AppRegistry.registerComponent('AHelloProject', () => ShowImage);
    

    运行结果:

    运行结果.png

    ScrollView组件

    ScrollView 组件的是简单实现,实现监测拖拽,滑动的相关方法

    import React, { Component } from 'react';
    import {
      AppRegistry,
      StyleSheet,
      Text,
      View,
      ScrollView,
      RefreshControl
    } from 'react-native';
    
    /*
      ScrollView 组件的是简单实现,实现监测拖拽,滑动的相关方法
    */
    
    var MyScrollView = React.createClass({
      _onScrollBeginDrag: function () {
          console.log("开始拖拽")
      },
      _onScrollEndDrag: function () {
        console.log("结束拖拽");
      },
      _onMomentumScrollBegin: function () {
        console.log("开始滑动");
      },
      _onMomentumScrollEnd: function () {
        console.log("滑动结束");
      },
      _onRefresh: function () {
        console.log("刷新");
      },
      render: function () {
        return (
          <View style={styles.container}>
            <ScrollView
            style={styles.scrollView}
            showVerticalScrollIndicator={true}
            onScrollBeginDrag = {this._onScrollBeginDrag}
            onScrollEndDrag = {this._onScrollEndDrag}
            onMomentumScrollBegin = {this._onMomentumScrollBegin}
            onMomentumScrollEnd = {this._onMomentumScrollEnd}
            // 刷新组件
            refreshControl={
              <RefreshControl
                refreshing={false}
                tintColor="red"
                title="正在刷新..."
                onRefresh={this._onRefresh}
              />
            }
            >
              <View style={[styles.layout, styles.view_1]}></View>
              <View style={[styles.layout, styles.view_2]}></View>
              <View style={[styles.layout, styles.view_3]}></View>
            </ScrollView>
          </View>
        );
      }
    });
    
    var styles = StyleSheet.create({
      container: {
        flex: 1,
        backgroundColor: "cyan"
      },
      scrollView: {
        marginTop: 25,
        backgroundColor: "#CCCCCC"
      },
      layout: {
        margin: 15,
        flex: 1,
        height: 300,
      },
      view_1: {
        backgroundColor: "red"
      },
      view_2: {
        backgroundColor: "yellow"
      },
      view_3: {
        backgroundColor: "blue"
      },
    });
    
    module.exports = MyScrollView;
    

    代码示例:

    ScrollView组件效果展示.png

    下边用ScrollView组件实现一个电影列表
    数据源地址:

    https://raw.githubusercontent.com/facebook/react-native/master/docs/MoviesExample.json

    返回的是JSON数据

    用一个本地文件命名为data.json来存储接口中返回的数据

    // 从文件中读取数据。执行JSON.parse(),将JSON格式的字符串转换成JSON格式对象
    var movieData = require("./data.json");
    // 获取所有movies数据。属性movies是一个数组
    var movies = movieData.movies;
    
    var MovieList = React.createClass({
      render: function () {
        // 处理数据,创建电影列表组件,根据movies中元素的个数,创建对应的组件
        // 遍历数组。每当获取一个movie对象,就创建一个组件对象。样式一样,显示内容不一样
    
        // 定义空数组。存储显示电影信息的组件
        var moviesRows = [];
        // 遍历数组
        for (var i in movies) {
          // 获取movie对象
          var movie = movies[i];
          // 创建组件,显示电影信息。图像(movie.posters.thumbnail)、电影名称(movie.title)、上映时间(movie.year)
          var row = (
            <View key={i} style={styles.row}>
              <Image style={styles.thumbnail} source={{uri:movie.posters.thumbnail}}/>
              <View style={styles.rightContainer}>
                <Text style={styles.title}>{movie.title}</Text>
                <Text style={styles.year}>{movie.year}</Text>
              </View>
            </View>
          );
          // 将创建的组件存储到数组中
          moviesRows.push(row);
        }
        return (
          <View style={styles.container}>
            <ScrollView style={styles.scrollView}>
              {
                // 数组(所有子组件)
                moviesRows
              }
            </ScrollView>
          </View>
        );
      }
    });
    
    var styles = StyleSheet.create({
      container: {
        flex: 1
      },
      scrollView: {
        flex: 1,
        marginTop: 25,
        backgroundColor: "#F5FCFF"
      },
      row: {
        flexDirection: "row",
        padding: 5,
        alignItems: "center",
        backgroundColor: "#F5FCFF"
      },
      thumbnail: {
        width: 53,
        height: 81,
        backgroundColor: "gray"
      },
      rightContainer: {
        marginLeft: 10,
        flex: 1
      },
      title: {
        fontSize: 18,
        marginTop: 3,
        marginBottom: 3,
        textAlign: "center",
      },
      year: {
        marginBottom: 3,
        textAlign: "center"
      },
    
    });
    
    module.exports = MovieList;
    

    代码示例:

    电影列表展示.png

    长列表FlatList或是SectionList组件

    React Native提供了几个适用于展示长列表数据的组件,一般而言我们会选用FlatList或是SectionList。

    FlatList组件用于显示一个垂直的滚动列表,其中的元素之间结构近似而仅数据不同。FlatList更适于长列表数据,且元素个数可以增删。和ScrollView不同的是,FlatList并不立即渲染所有元素,而是优先渲染屏幕上可见的元素。FlatList组件必须的两个属性是data和renderItem。data是列表的数据源,而renderItem则从数据源中逐个解析数据,然后返回一个设定好格式的组件来渲染。

    下面的例子创建了一个简单的FlatList,并预设了一些模拟数据。首先是初始化FlatList所需的data,其中的每一项(行)数据之后都在renderItem中被渲染成了Text组件,最后构成整个FlatList。

    import React, { Component } from 'react';
    import {
      StyleSheet,
      Text,
      View,
      FlatList,
    } from 'react-native';
    
    class FlatListDemo extends Component {
      render() {
        return (
          <View style={styles.container}>
            <FlatList
              data={[
                {key: 'Devin'},
                {key: 'Jackson'},
                {key: 'James'},
                {key: 'Joel'},
                {key: 'John'},
                {key: 'Jillian'},
                {key: 'Jimmy'},
                {key: 'Julie'},
              ]}
              renderItem={({item}) => <Text style={styles.item}>{item.key}</Text>}
            />
          </View>
        );
      }
    }
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        paddingTop: 22
      },
      item: {
        padding: 10,
        fontSize: 18,
        height: 44
      },
    });
    
    module.exports = FlatListDemo;
    

    运行效果:

    运行效果.png

    ListView组件

    ListView 数据列表组件。ListView最重要的是设置每行显示的组件 section、header。使用listView.dataSource,给它设置一个普通的数据数组,再使用dataSource对象实例化一个ListView组件。

    ListView实现: row/section组件定义,设置数据
    设置ListView数据源:将dataSource对象设置为state的对象

    示例1

    // 原始数据:数组(字符串)
    var contents = [
      "iOS",
      "Java",
      "JavaScript",
      "ReactNative",
      "PHP",
      "Swift",
      "Kotlin",
      "Ajax",
    ];
    var MyListView = React.createClass({
      getInitialState: function () {
        // 创建dataSource对象
        var ds = new ListView.DataSource({
          // 通过判断决定渲染哪些行组件,避免全部渲染,提高渲染效率
          rowHasChanged: (oldRow, newRow) => oldRow == newRow
        });
    
        return {
          // 设置DataSource时,不直接使用提供的原始怇,使用cloneWithRows对数据源进行复制
          // 使用复制后的数据源实例化ListView。优势:当原始数据源发生变化时,ListView组件的DataSource不会改变
          dataSource: ds.cloneWithRows(contents)
        };
      },
    
      // 渲染行组件,参数是每行要显示的数据对象
      _renderRow: function (rowData: String) {
        return(
          <View style={styles.row}>
            <Text style={styles.content}>{rowData}</Text>
          </View>
        );
      },
      render: function () {
        return(
          <ListView
            style={styles.container}
            dataSource={this.state.dataSource}
            renderRow={this._renderRow}
          />
        );
      }
    });
    
    var styles = StyleSheet.create({
      container: {
        flex: 1,
        marginTop: 25
      },
      row: {
        justifyContent: "center",
        alignItems: "center",
        padding: 5,
        height: 100,
        borderBottomWidth: 1,
        borderColor: "#CCC"
      },
      content: {
        flex: 1,
        fontSize: 20,
        color: "blue",
        lineHeight: 100
      }
    });
    
    module.exports = MyListView;
    

    运行结果:

    运行结果.png

    示例2-用ListView重写ScrollView部分的列表

    import React, { Component } from 'react';
    import {
      AppRegistry,
      StyleSheet,
      Text,
      View,
      ListView,
      Image
    } from 'react-native';
    
    // 从文件中读取数据
    var movieData = require("./data.json");
    // 获取所有Movies数据,属性movies是一个数组
    // 这个是ListView的原始数据
    var movies = movieData.movies;
    
    var MovieListView = React.createClass({
      getInitialState: function () {
        // 创建DataSource对象
        var ds = new ListView.DataSource({
          rowHasChanged: (oldValue, newValue) => oldValue != newValue
        });
    
        return{
          dataSource: ds.cloneWithRows(movies)
        };
      },
      // 渲染行row组件
      _renderRow: function (movie) {
        return (
          <View style={styles.row}>
            <Image style={styles.thumbnail} source={{uri: movie.posters.thumbnail}}/>
            <View style={styles.rightContainer}>
              <Text style={styles.title}>{movie.title}</Text>
              <Text style={styles.year}>{movie.year}</Text>
            </View>
          </View>
        );
      },
      // 渲染头部
      _renderHeader: function () {
        return (
          <View style={styles.header}>
            <Text style={styles.header_text}>Movie List</Text>
            <View style={styles.separator}></View>
          </View>
        );
      },
      // 渲染分割线
      _renderSeparator: function (sectionID: number, rowID: number) {
        return(
          <View style={styles.separator} key={sectionID + rowID}></View>
        );
      },
    
      render: function () {
        return(
          <ListView
            style={styles.listView}
            dataSource={this.state.dataSource}
            renderRow={this._renderRow}
            renderHeader={this._renderHeader}
            renderSeparator={this._renderSeparator}
            // 一开始渲染10行,提高渲染效率来用
            initialListSize={10}
          />
        );
      }
    });
    
    var styles = StyleSheet.create({
      listView: {
        marginTop: 25,
        flex: 1,
        backgroundColor: "#F5FCFF",
      },
      // 航组件样式
      row: {
        flexDirection: "row",
        padding: 5,
        alignItems: "center",
        backgroundColor: "#F5FCFF",
      },
      thumbnail: {
        width: 53,
        height: 81,
        backgroundColor: "gray"
      },
      rightContainer: {
        marginLeft: 10,
        flex: 1
      },
      title: {
        fontSize: 18,
        marginTop: 3,
        marginBottom: 3,
        textAlign: "center"
      },
      year: {
        marginBottom: 3,
        textAlign: "center"
      },
      // Header组件样式
      header: {
        height: 44,
        backgroundColor: "#F5FCFF"
      },
      header_text: {
        flex: 1,
        fontSize: 20,
        fontWeight: "bold",
        textAlign: "center",
        lineHeight: 44
      },
      // 分割线组件样式
      separator: {
        height: 1,
        backgroundColor: "#CCC"
      },
    
    });
    
    module.exports = MovieListView;
    

    运行效果:

    运行效果.png

    Navigator组件

    应用程序由很多功能视图组成,一个应用中重要的功能之一就是“导航”,在ReactNative中称为“路由route”。使用导航可以让你在应用的不同场景(页面)间进行切换

    • 在ReactNative中,有两个实现导航功能的组件:Navigator和NavigatorIOS
    • Navigator支持安卓和iOS,NavigatorIOS只支持iOS
    • NavigatorIOS比Navigator具有更多的属性和方法,在UI方面可以进行更多设置,例如:backButtonIcon、backButtonTitle、onLeftButtonPress等等,比较方便。
    • 如果想实现更多的自定义设置,建议使用Navigator

    从0.44版本开始,Navigator被从react native的核心组件库中剥离到了一个名为react-native-deprecated-custom-components的单独模块中。如果你需要继续使用Navigator,则需要先npm i -S react-native-deprecated-custom-components,然后从这个模块中import,即import { Navigator } from 'react-native-deprecated-custom-components'.

    导航器通过路由对象(route)来分辨不同的场景。每个路由对象都对应一个页面组件,开发者设置什么,导航器显示什么所以route是导航器中重要的一个对象。

    三步操作实现导航功能:

    • 1、设置路由对象(告诉导航器我要显示哪个页面)。创建路由对象,对象的内容自定义,但是必须包含该场景需要展示的页面组件
    • 2、场景渲染配置(告诉导航器我要什么样的页面跳转效果)
    • 3、渲染场景(告诉导航器如何渲染页面)
      利用第一步设置的路由对象进行渲染场景

    示例1--下边代码示例实现了导航功能,页面切换

    // 定义第一个页面
    // FirstPage 一个Button,点击进入下一级页面
    var FirstPage = React.createClass({
        // 按钮onPress事件处理方法
        pressPush: function () {
          // 推出下一个页面
          this.props.navigator.push({component: SecondPage});
        },
        render: function () {
          return(
            <View style={[styles.flex, {backgroundColor: "yellow"}]}>
              <TouchableOpacity style={styles.btn} onPress={this.pressPush}>
                <Text>点击进入下一级页面</Text>
              </TouchableOpacity>
            </View>
          );
        }
    });
    
    // 定义第二个页面
    // SecondPage 一个Button,点击返回上一级页面
    var SecondPage = React.createClass({
        // 按钮onPress事件处理方法
        pressPop: function () {
          // 返回上一个页面
          this.props.navigator.pop();
        },
        render: function () {
          return(
            <View style={[styles.flex, {backgroundColor: "cyan"}]}>
              <TouchableOpacity style={styles.btn} onPress={this.pressPop}>
                <Text>点击返回上一级页面</Text>
              </TouchableOpacity>
            </View>
          );
        }
    });
    
    var NavigatorDemo = React.createClass({
      render: function () {
        var rootRoute = {
            component: FirstPage
        };
    
        return (
          <Navigator
            /*
              第一步:initialRoute初始化路由对象,这个指定了默认的页面,也就是启动页面后看到的第一屏
              对象的属性时自定义的,这个对象中的内容会在renderScene方法中处理
              备注:必须包含的属性,即上边代码中的component,表示需要渲染的页面组件
            */
            initialRoute={rootRoute}
            /*
              第二步:configureScene 场景渲染的配置
            */
            configureScene={(route) => {
              return Navigator.SceneConfigs.PushFromRight
            }}
            /*
              第三步:renderScene 渲染场景
              备注: route(第一步创建并设置给导航器的路由对象),navigator(导航器对象)
              实现: 给需要显示的组件设置属性
            */
            renderScene={(route, navigator) => {
              // 从route对象中获取页面组件
              var Component = route.component;
              return (
                <Component
                  navigator={navigator}
                  route={route}
                />
              );
            }}
          />
        );
      }
    });
    
    var styles = StyleSheet.create({
      flex: {
        flex: 1,
        alignItems: "center",
        justifyContent: "center"
      },
      btn: {
        width: 150,
        height: 30,
        borderColor: "#0089FF",
        borderWidth: 1,
        borderRadius: 3,
        justifyContent: "center",
        alignItems: "center"
      },
    });
    
    module.exports = NavigatorDemo;
    

    运行结果


    运行结果.png

    示例2--下边代码示例实现了导航功能,传值

    import React, { Component } from 'react';
    import {
      AppRegistry,
      StyleSheet,
      Text,
      View,
      TouchableOpacity,
      TextInput
    } from 'react-native';
    import {
      Navigator
    } from 'react-native-deprecated-custom-components';
    
    // 实现导航功能,传值
    // 定义InputPage页面,输入框,按钮
    var InputPage = React.createClass({
        getInitialState: function () {
          return {
            // 记录输入框的值
            content: " "
          };
        },
        getInputContent: function (inputText) {
          // 将输入框的值进行记录
          this.setState({
            content: inputText
          });
        },
        // 按钮onPress事件处理方法
        pressPush: function () {
          // 推出下一个页面并传值 创建一个route对象
          var route = {
            component: DetailPage,
            passProps: {
              // 将输入框的数据传入到下一个页面
              showText: this.state.content
            }
          };
          this.props.navigator.push(route);
        },
        render: function () {
          return(
            <View style={inputStyles.container}>
              <TextInput
                style={inputStyles.input}
                placeholder="请输入内容"
                onChangeText={this.getInputContent}
              />
              <TouchableOpacity style={inputStyles.btn} onPress={this.pressPush}>
                <Text>进入下一页</Text>
              </TouchableOpacity>
            </View>
          );
        }
    });
    
    var inputStyles = StyleSheet.create({
      container: {
        flex: 1,
        alignItems: "center",
        justifyContent: "center",
        backgroundColor: "white"
      },
      input: {
        height: 45,
        marginLeft: 25,
        marginRight: 25,
        paddingLeft: 5,
        borderWidth: 1,
        borderColor: "black",
        borderRadius: 4
      },
      btn: {
        marginTop: 20,
        height: 30,
        borderWidth: 1,
        borderRadius: 4,
        borderColor: "black",
        padding: 5,
        justifyContent: "center",
        alignItems: "center"
      },
    });
    
    // 定义第二个页面
    // DetailPage 一个Button,点击返回上一级页面,一个显示文本
    var DetailPage = React.createClass({
        // 按钮onPress事件处理方法
        pressPop: function () {
          // 返回上一个页面
          this.props.navigator.pop();
        },
        render: function () {
          return(
            <View style={detailStyles.container}>
              <Text style={detailStyles.text}>{this.props.showText}</Text>
              <TouchableOpacity style={detailStyles.btn} onPress={this.pressPop}>
                <Text>返回上一页</Text>
              </TouchableOpacity>
            </View>
          );
        }
    });
    
    var detailStyles = StyleSheet.create({
      container: {
        flex: 1,
        justifyContent: "center",
        alignItems: "center",
        backgroundColor: "white"
      },
      text: {
        marginLeft: 25,
        marginRight: 25,
        padding: 25,
        backgroundColor: "cyan",
        fontSize: 20,
        textAlign: "center"
      },
      btn: {
        marginTop: 20,
        height: 30,
        borderWidth: 1,
        borderRadius: 4,
        borderColor: "black",
        padding: 5,
        justifyContent: "center",
        alignItems: "center"
      }
    
    });
    
    var NavigatorDemo = React.createClass({
      render: function () {
        var rootRoute = {
            component: InputPage,
            // 存储需要传值的内容
            passProps: {
    
            }
        };
    
        return (
          <Navigator
            initialRoute={rootRoute}
            configureScene={(route) => {
              return Navigator.SceneConfigs.PushFromRight
            }}
            renderScene={(route, navigator) => {
              var Component = route.component;
              return (
                <Component
                  navigator={navigator}
                  route={route}
                  // 传值
                  {...route.passProps}
                />
              );
            }}
          />
        );
      }
    });
    
    module.exports = NavigatorDemo;
    
    运行效果.png

    TabBarIOS组件

    在ReactNative中,实现页面切换,提供了两个组件:TabBarIOS和TabBarIOS.item
    常用属性:

    • selected: 是否选中某个Tab,如果为true则选中并显示组件
    • title: 标题
    • barTintColor: Tab栏的背景颜色
    • icon: 图标
    • onPress: 点击事件,当某个tab被选中时,需要改变组件的selected={true}设置

    实现原理:点击tab时触发onPress方法,记录被点击tab的title,再通过title设置tab是否被选中,通过比较设置selected的值,true/false

    // 把NewsListShow组件,TextInputDemo组件,BlinkShow组件集成到TabBarIOS中
    var NewsListShow = require("./newsListShow.js");
    var BlinkDemo = require("./blinkShow.js");
    var TextInputDemo = require("./textInputDemo.js");
    
    var TabBarIOSDemo = React.createClass({
      getInitialState: function () {
        return {
          // 用于记录显示页面组件对应的title,设置默认的
          tab: "TextInput"
        };
      },
      // TabBarIOS.Item的onPress的处理方法
      select: function (tabName) {
        this.setState({
          tab: tabName
        });
      },
      render: function () {
        return (
          <TabBarIOS style={{flex: 1}}>
            <TabBarIOS.Item
              title = "TextInput"
              icon={require("../image/index1@2x.png")}
              onPress={this.select.bind(this, "TextInput")}
              selected={this.state.tab === "TextInput"} >
              <TextInputDemo></TextInputDemo>
            </TabBarIOS.Item>
            <TabBarIOS.Item
              title = "Blink"
              icon={require("../image/index2@2x.png")}
              onPress={this.select.bind(this, "Blink")}
              selected={this.state.tab === "Blink"} >
              <BlinkDemo></BlinkDemo>
            </TabBarIOS.Item>
            <TabBarIOS.Item
              title = "NewsList"
              icon={require("../image/index3@2x.png")}
              onPress={this.select.bind(this, "NewsList")}
              selected={this.state.tab === "NewsList"} >
              <NewsListShow></NewsListShow>
            </TabBarIOS.Item>
          </TabBarIOS>
        );
      }
    });
    
    module.exports = TabBarIOSDemo;
    

    运行结果:

    运行结果.png

    相关文章

      网友评论

          本文标题:ReactNative组件介绍

          本文链接:https://www.haomeiwen.com/subject/xvricxtx.html