美文网首页
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