React Native从零开始(八)ListView网络获取数据(Fetch)显示

React Native从零开始(八)ListView网络获取数据(Fetch)显示





先上效果图:




一、思路


实现这个效果,我们需要了解ListView的实现和Fetch的实现方法,并将其结合,这两个知识点在前两篇博客中已经有写到,其实没有什么难点,也可以加上页面等待时的一个效果,在数据未加载完成时我们可以显示Text,提示正在下载

二、实现

1、我们需要设置State来存储数据的状态,在未下载完成时为false完成时则设置成true


    constructor(props){
        super(props);
        var ds = new ListView.DataSource({
           rowHasChanged:(oldRow,newRow) => oldRow!==newRow
        });
        this.state = {
            /*1设置初始值*/
            loaded: false,
            dataSource:ds
        };
    }

这个时候创建一个DataSource来判断这两行是否相同,就是是否发生变化,决定渲染哪些行组件,避免全部渲染,提高渲染效率。

2、创建一个方法来实现数据的下载

  //下载数据
    getData() {
    fetch(REQUEST_URL)
        .then((response) => {
            return response.json();
        })
        .then((responseData) => {
            this.setState({
                loaded:true,
                dataSource:this.state.dataSource.cloneWithRows(responseData.movies)
            });
        })
}

这里第二个then的话是数据下载成功,我们将state的值重新赋值,然后将下载的数据克隆,是的dataSource不使用原数据。


3、使用componentDidMount方法来执行数据的下载,这个方法是在组件挂载后开始执行的

    //组件挂载完成后执行的方法
    componentDidMount(){
        //组件挂载后开始下载数据
        this.getData();
    }


4、渲染ListView的头部、行、和分割线

//渲染行组件
function _renderRow(movie){
    return(
        <View style={styles.row}>
            <Image
                style={styles.thumbnail}
                source={{uri:movie.posters.thumbnail}}/>
            <View >
                <Text >{movie.title}</Text>
                <Text >{movie.year}</Text>
            </View>
        </View>
    );
}
//渲染头部
function _renderHeader(){
    return(
        <View >
            <Text >Movies List</Text>
            <View ></View>
        </View>
    );
}
//渲染分割线
function _renderSeparator(sectionId,rowId){
    return(
        <View
            style={styles.separator}
            key={sectionId+rowId}></View>
    );
}



5、根据state的不同的值来渲染不同的控件


    render(){
        /*2如果未请求到数据提示等待加载,如果请求到数据显示
         * */
        //加载前
        if(!this.state.loaded){
            return LoadingView();
        }
        //加载后
        return (
            <ListView
                style={styles.listView}
                dataSource={this.state.dataSource}
                renderRow={_renderRow}
                renderHeader={_renderHeader}
                renderSeparator={_renderSeparator}
                initialListSize={10}
            />
        );
    }

6、在index页面调用这个控件就好

var MyListView = require("./MyView/MyListView");
export default class MovieListView extends Component {
  render() {
    return (
      <MyListView/>
    );
  }
}




三、最后附上所有代码

MyListView.js

/**
 * Created by 11158 on 2017-01-17.
 */
import React, { Component } from 'react';
import {
    AppRegistry,
    StyleSheet,
    Text,
    View,
    Image,
    ListView
} from 'react-native';

var REQUEST_URL = "https://raw.githubusercontent.com/facebook/react-native/master/docs/MoviesExample.json";
/*
    逻辑:未获取数据时,显示等待页面;获得数据时,显示电影列表页面
    需要用到state的属性,用于记录下载状态
* */
//未下载完数据显示的页面
function LoadingView() {
    return (
        <View style={styles.loadingContainer}>
            <Text style={styles.loadingText}>Loading Movies......</Text>
        </View>
    );
}
//渲染行组件
function _renderRow(movie){
    return(
        <View style={styles.row}>
            <Image
                style={styles.thumbnail}
                source={{uri:movie.posters.thumbnail}}/>
            <View >
                <Text >{movie.title}</Text>
                <Text >{movie.year}</Text>
            </View>
        </View>
    );
}
//渲染头部
function _renderHeader(){
    return(
        <View >
            <Text >Movies List</Text>
            <View ></View>
        </View>
    );
}
//渲染分割线
function _renderSeparator(sectionId,rowId){
    return(
        <View
            style={styles.separator}
            key={sectionId+rowId}></View>
    );
}
class MyListView extends Component{
    constructor(props){
        super(props);
        var ds = new ListView.DataSource({
           rowHasChanged:(oldRow,newRow) => oldRow!==newRow
        });
        this.state = {
            /*1设置初始值*/
            loaded: false,
            dataSource:ds
        };
    }
    //组件挂载完成后执行的方法
    componentDidMount(){
        //组件挂载后开始下载数据
        this.getData();
    }
    //下载数据
    getData() {
    fetch(REQUEST_URL)
        .then((response) => {
            return response.json();
        })
        .then((responseData) => {
            this.setState({
                loaded:true,
                dataSource:this.state.dataSource.cloneWithRows(responseData.movies)
            });
        })
}
    render(){
        /*2如果未请求到数据提示等待加载,如果请求到数据显示
         * */
        //加载前
        if(!this.state.loaded){
            return LoadingView();
        }
        //加载后
        return (
            <ListView
                style={styles.listView}
                dataSource={this.state.dataSource}
                renderRow={_renderRow}
                renderHeader={_renderHeader}
                renderSeparator={_renderSeparator}
                initialListSize={10}
            />
        );
    }
}

const styles = StyleSheet.create({
    //loading样式
    loadingContainer:{
        flex:1,
        marginTop:25,
        backgroundColor:"cyan",
        justifyContent:"center",
        alignItems:"center"
    },
    loadingText:{
        fontSize:30,
        fontWeight:"bold",
        textAlign:"center",
        marginLeft:10
        ,marginRight:10
    },
    //行样式
    row:{
        flexDirection:"row",
        padding:5,
        alignItems:"center",
        backgroundColor:"#F5FCFF"
    },
    //图片样式
    thumbnail:{
        width:53,
        height:81,
        backgroundColor:"gray"
    },
    //分割线样式
    separator:{
        height:1,
        backgroundColor:"black"
    },
    listView:{
        marginTop:25,
        backgroundColor:"#F5FCFF"
    },
});

module.exports = MyListView;



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

import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View
} from 'react-native';
var MyListView = require("./MyView/MyListView");
export default class MovieListView extends Component {
  render() {
    return (
      <MyListView/>
    );
  }
}

const styles = StyleSheet.create({

});

AppRegistry.registerComponent('MovieListView', () => MovieListView);






大家可以加好友交流学习
QQ:1115856293
微信:




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值