React-Native中一些组件的用法(二)

个人博客搭建完成,欢迎大家来访问哦
黎默丶lymoo的博客

本文为大家介绍一下React-Native中一些深入些的组件,由于对ES6的语法并没有完全掌握,这里暂时用ES5和ES6混用的语法。

ScrollView组件

能够调用移动平台的ScrollView(滚动视图)的组件,同时还集成了触摸锁定的“响应者”系统。
注意一定要给scrollview一个高度,或者是他父级的高度。

常用方法

onScrollBeginDrag:开始拖拽的时候;
onScrollEndDrag:结束拖拽的时候;
onMomentumScrollBegin:开始滑动;
onMomentumScrollEnd:开始滑动;

特殊组件

RefreshControl 以用在ScrollView或ListView内部,为其添加下拉刷新的功能。
当ScrollView处于竖直方向的起点位置(scrollY: 0),此时下拉会触发一个onRefresh事件。

示例

创建一个scroll.js文件
代码如下:

import React, { Component } from 'react';
import {
    StyleSheet,
    View,
    ScrollView,
    RefreshControl
} from 'react-native';
var dataSource = require("./data.json");
// 创建组件
var ScrollTest = React.createClass({
    // 下面的几种函数可以根据自己的需求添加
    _onScrollBeginDrag () {
       // 这里是开始拖拽的函数
    },
    _onScrollEndDrag () {
       // 这里是拖拽结束的函数
    },
    _onMomentumScrollBegin () {
       // 这里是开始滚动的函数
    },
    _onMomentumScrollEnd () {
       // 这里是滚动结束的函数
    },
    _refresh () {
       // 这里是请求数据的函数
       alert("正在请求数据");
    },
    render () {
        return (
            <ScrollView style={styles.container}
                        onScrollBeginDrag={this._onScrollBeginDrag}
                        onScrollEndDrag={this._onScrollEndDrag}
                        onMomentumScrollBegin={this._onMomentumScrollBegin}
                        onMomentumScrollEnd={this._onMomentumScrollEnd}
                        refreshControl={
                            <RefreshControl refreshing={false}
                                            titleColor={"red"}
                                            title={"正在刷新......."}
                                            tintColor={"cyan"}
                                            onRefresh={this._refresh} />
                        }>
                <View style={[styles.item, styles.item1]}></View>
                <View style={[styles.item, styles.item2]}></View>
                <View style={[styles.item, styles.item3]}></View>
            </ScrollView>
        )
    }
});
// 实例化样式
var styles = StyleSheet.create({
    container: {
        marginTop: 25,
        height: 300,
        borderWidth: 1,
        borderColor: "#ccc"
    },
    item: {
        width: 280,
        height: 150,
        margin: 20
    },
    item1: {
        backgroundColor: "red"
    },
    item2: {
        backgroundColor: "green"
    },
    item3: {
        backgroundColor: "yellow"
    }
});
module.exports = ScrollTest;

再将index.ios.js文件改成如下:

import React, { Component } from 'react';
import {
  AppRegistry,
  View,
} from 'react-native';
var Scroll = require("./scroll");
var ScrollTest = React.createClass({
    render () {
      return (
          <View>
            <Scroll></Scroll>
          </View>
      )
    }
});
AppRegistry.registerComponent('useComponent', () => ScrollTest);

最终效果:
ScrollView组件效果展示
ScrollView组件效果展示

ListView组件

用于高效地显示一个可以垂直滚动的变化的数据列表。
最基本的使用方式就是创建一个ListView.DataSource数据源,然后给它传递一个普通的数据数组,再使用数据源来实例化一个ListView组件,并且定义它的renderRow回调函数,这个函数会接受数组中的每个数据作为参数,返回一个可渲染的组件(作为listview的每一行)。

数据处理

ListView.DataSource为ListView组件提供高性能的数据处理和访问。
我们需要调用方法从原始输入数据中抽取数据来创建ListViewDataSource对象,并用其进行数据变更的比较。
DataSource初始化:

getInitialState:function () {
//  实例化DataSource对象
    var ds = new ListView.DataSource({
        rowHasChanged:(oldData,newData) => oldData !== newData
    });
    return {
        data:ds.cloneWithRows(news)
    }
}

常用属性

设置数据源:dataSource={this.state.dataSource}
设置列表组件:renderRow={this._renderRow}
设置ListView头部:renderHeader={this._renderHeader}
设置列表项之间的间隔:renderSeparator={this._renderSeparator}

示例 制作一个电影列表

博主先前从猫眼电影里获取了一些电影介绍的json文件,有兴趣的同学可以去猫眼电影列表获取一些信息,注意这里需要json格式转换一下!
这里创建一个movieList.js的文件
代码如下:

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

// 通过ListView实现电影列表
var movies = require("./data.json").data.movies;

// 创建组件
var ListMovie = React.createClass({
    getInitialState () {
        var ds = new ListView.DataSource({
            rowHasChanged: (oldData, newData) => oldData !== newData
        });
        return {dataSource: ds.cloneWithRows(movies)}
    },
    _renderRow (movie) {
        return (
            <View style={styles.row}>
                <Image style={styles.img} source={{uri: movie.img}}/>
                <View style={styles.right}>
                    <Text style={styles.name}>{movie.nm}</Text>
                    <Text style={styles.dir}>导演:{movie.dir}</Text>
                    <Text style={styles.dir}>上映时间:{movie.rt}</Text>
                </View>
            </View>
        )
    },
    _renderHeader () {
        return (
            <View style={styles.header}>
                <Text style={styles.title}>猫眼热门电影</Text>
                <View style={[styles.separator, {width: "100%"}]}></View>
            </View>
        )
    },
    _renderSeparator () {
        return <View style={styles.separator}></View>
    },
    render () {
        return <ListView style={styles.container}
                         dataSource={this.state.dataSource}
                         renderRow={this._renderRow}
                         renderHeader={this._renderHeader}
                         renderSeparator={this._renderSeparator}
               />
    }
});

// 实例化样式
var styles = StyleSheet.create({
    container: {
        marginTop: 25
    },
    row: {
        flexDirection: "row",
        alignItems: "center",
        padding: 10
    },
    img: {
        width: 78,
        height: 128
    },
    right: {
        marginLeft: 15,
        flex: 1
    },
    name: {
        fontSize: 20,
        fontWeight: "bold",
        marginTop: 3,
        marginBottom: 10
    },
    dir: {
        fontSize: 15,
        marginBottom: 3,
        color: "#686868"
    },
    header: {
        height: 44,
        alignItems: "center"
    },
    title: {
        fontSize: 25,
        fontWeight: "bold",
        lineHeight: 44
    },
    separator: {
        height: 1,
        backgroundColor: "#ccc"
    }
});
module.exports = ListMovie;

再将index.ios.js文件改成如下:

import React, { Component } from 'react';
import {
  AppRegistry,
  View,
} from 'react-native';
var ListMovie = require("./listMovie");
var Movie = React.createClass({
    render () {
      return (
          <View>
            <ListMovie></ListMovie>
          </View>
      )
    }
});
AppRegistry.registerComponent('useComponent', () => Movie);

最终效果:
ScrollView组件效果展示

Navigator组件

使用导航器可以让你在应用的不同场景(页面)间进行切换。其实质上类似于HTML里导航条功能。
不过导航器页面的跳转需要通过路由对象来分辨不同的场景。
利用renderScene方法,导航栏可以根据指定的路由来渲染场景。

导航器的设置步骤

第一步:设置属性initialRoute:初始化route对象,指定默认页面,也就是启动app之后所看到的第一个页面;
第二步:configureScene:配置场景动画和手势;
第三步:renderScene;渲染场景,参数route(第一步创建并设置的导航器路由对象),navigator(导航器对象)
代码展示:

<Navigator
    initialRoute={rootRoute}
    configureScene={(route)=>Navigator.SceneConfigs.PushFromRight}
    renderScene={
        (route,navigator)=>{
            var MySceneComponent = route.component;
            console.log(MySceneComponent);
            console.log(“aaaa”);
            return (
                <MySceneComponent route={route} navigator={navigator}/>
            )
        }
    }
/>

示例

创建一个nav.js文件
代码如下:

/**
 * Created by lanou on 17/4/13.
 */
import React, { Component } from 'react';
import {
    StyleSheet,
    Text,
    View,
    Navigator,
    TouchableOpacity,
    TextInput
} from 'react-native';

// 在进行导航时,需要先构成一些页面,使用Navigator

// 创建组件
var FirstPage = React.createClass({
    getInitialState () {
        return {text: ""}
    },
    saveText (text) {
        this.setState({text: text})
    },
    changePage () {
        // 把需要传递的值,都放在路由的nextPass属性里
        var nextRoute = {
            component: SecondPage,
            nextPass: {text: this.state.text}
        };
        this.props.navigator.push(nextRoute);
    },
    render () {
        return (
            <View style={[styles.container, {backgroundColor: "cyan"}]}>
                <TextInput style={styles.input} placeholder={"请输入"} onChangeText={this.saveText}/>
                <TouchableOpacity onPress={this.changePage} style={styles.btn}>
                    <Text style={styles.btnText}>跳转到下一页</Text>
                </TouchableOpacity>
            </View>
        )
    }
});

var SecondPage = React.createClass({
    changePage () {
        this.props.navigator.pop();
    },
    render () {
        return (
            <View style={[styles.container, {backgroundColor: "yellowgreen"}]}>
                <Text>接收到的数据是{this.props.text}</Text>
                <TouchableOpacity onPress={this.changePage} style={styles.btn}>
                    <Text style={styles.btnText}>返回上一页</Text>
                </TouchableOpacity>
            </View>
        )
    }
});

var Nav = React.createClass({
    render () {
        // 初始路由,首页
        var rootRoute = {
            component: FirstPage,
            nextPass: {}
        };
        return (
            <Navigator
                // 第一步需要进行初始路由的设置
                initialRoute={rootRoute}
                // 第二步设置页面的切换方式
                configureScene={(route) => Navigator.SceneConfigs.FloatFromBottom}
                // 第三部确定要渲染的场景(页面)
                renderScene={(route, navigator) => {
                    // 找到要渲染的页面
                    var Component = route.component;
                    // 渲染时,需要把route和Navigator作为属性传递下去,传递的值也作为属性传递
                    // ...route.nextPass把route中的nextPass里的数据都传递下去
                    return <Component {...route.nextPass} text={route.nextPass.text} route={route} navigator={navigator} />
                }}
            />
        )
    }
});

// 实例化样式
var styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: "center",
        alignItems: "center",
    },
    btn: {
        backgroundColor: "#25f30d",
        width: 115,
        height: 30,
        borderRadius: 5,
        justifyContent: "center",
        alignItems: "center"
    },
    btnText: {
        fontSize: 14,
        fontWeight: "bold"
    },
    input: {
        margin: 30,
        borderWidth: 1,
        borderColor: "#ccc",
        height: 30,
        backgroundColor: "#77ccb1"
    }
});
module.exports = Nav;

在index.ios.js文件中代码更改如下:

import React, { Component } from 'react';
import {
  AppRegistry,
  View,
} from 'react-native';
var Nav = require("./nav");
var NavTest = React.createClass({
    render () {
      return (
          <View style={{flex: 1}}>
            <Nav></Nav>
          </View>
      )
    }
});
AppRegistry.registerComponent('useComponent', () => NavTest);

最终效果:
ScrollView组件效果展示
ScrollView组件效果展示

TableBarIOS组件

TableBar是放置在屏幕的最下方会有很多平级的标签图标的标签栏,用户可以击内部不同的图标切换屏幕中显示的视图,TableBarIOS只适用于IOS平台

常用属性

barTintColor:标签栏的背景颜色
tintColor:当前被选中标签图标的颜色
unselectedItemTintColor:当前没有被选中的标签图标的颜色

TabBarIOS.Item

TabBarIOS.Item是每个可以点击标签不图标,根据点击的不同显示不同的视图

常用属性

title:在图标下面显示的标题文字
icon:给当前标签指定一个自定义的图标
onPress:当此标签被选中时调用。你应该修改组件的状态来使得selected={true}
selected:这个属性决定了子视图是否可见。如果你看到一个空白的页面,很可能是没有选中任何一个标签。
代码展示:

<TabBarIOS.Item
    title=“movieTest”
    icon={require(“./passport.png”)}
    onPress={this.changeTab.bind(this, ”movieTest”)}
    selected={this.state.selectTab == “movieTest”}
>
    <MovieList></MovieList>
</TabBarIOS.Item>

示例

创建一个tabBar.js文件
代码如下:

import React, { Component } from 'react';
import {
    TabBarIOS
} from 'react-native';

//引入三个选项页面(这里引入的是之前做好的几个组件)
var Nav = require("./nav");
var MovieList = require("./movieList");
var ImageTest = require("./image");

var TabBarTest = React.createClass({
    getInitialState:function () {
        //显示当前显示的标签
        return {
            selectTab: "首页"
        }
    },
    changeTab:function (name) {
        this.setState({
            selectTab:name
        })
    },
    render:function () {
        return (
            <TabBarIOS barTintColor="#ccc"
                       tintColor={"red"}
                       unselectedItemTintColor={"cyan"}
            >
                {/*下部的标签栏*/}
                <TabBarIOS.Item
                    title="首页"
                    icon={require("./images/index.png")}
                    onPress={this.changeTab.bind(this,"首页")}
                    selected={this.state.selectTab == "首页"}
                >
                    {/*每一个选项*/}
                    <Input/>
                </TabBarIOS.Item>
                <TabBarIOS.Item
                    title="图片"
                    icon={require("./images/picture.png")}
                    onPress={this.changeTab.bind(this,"图片")}
                    selected={this.state.selectTab == "图片"}
                >
                    {/*每一个选项*/}
                    <ImageTest/>
                </TabBarIOS.Item>
                <TabBarIOS.Item
                    title="电影"
                    icon={require("./images/movie.png")}
                    onPress={this.changeTab.bind(this,"电影")}
                    selected={this.state.selectTab == "电影"}
                >
                    {/*每一个选项*/}
                    <MovieList/>
                </TabBarIOS.Item>
            </TabBarIOS>
        )
    }
});
module.exports = TabBarTest;

在index.ios.js文件中,代码更改为如下:

import React, { Component } from 'react';
import {
  AppRegistry,
  View,
} from 'react-native';
var TabBarTest = require("./tabBar");
var TabTest = React.createClass({
    render () {
      return (
          <View style={{flex: 1}}>
            <TabBarTest></TabBarTest>
          </View>
      )
    }
});
AppRegistry.registerComponent('useComponent', () => TabTest);

最终效果:
ScrollView组件效果展示
ScrollView组件效果展示

网络请求

React Native提供了和web标准一致的Fetch API,用于满足开发者访问网络的需求。与之前学过的AJAX很相似。
fetch()第一个参数为请求地址
fetch(‘https://mywebsite.com/mydata.json’);
第二个参数可选,可以用来定制HTTP请求一些参数

fetch(‘https://mywebsite.com/endpoint/‘, {
  method: ‘POST’,
  headers: {
    ‘Accept’: ‘application/json’,
    ‘Content-Type’: ‘application/json’,
  },
  body: JSON.stringify({
    firstParam: ‘yourValue’,
    secondParam: ‘yourOtherValue’,
  })
})

其中body表示要传输的数据
Fetch 方法会返回一个Promise,需要对返回的数据进行处理
通过链式结构添加then方法进行成功数据处理
如果有错,通过catch方式捕捉

getDate:function () {
    fetch(url)
        .then((res)=>{
            return res.json();
        })
        .then((resData)=>{
            this.setState({
                loaded:true,
                dataSource:this.state.dataSource.cloneWithRows(resData.data.movies)
            })
        })
        .catch((err)=>{
            alert(err)
        })
}

原文链接

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容