美文网首页
ReactNative之listView从0到1

ReactNative之listView从0到1

作者: Shmily鱼 | 来源:发表于2017-11-06 14:13 被阅读0次

    先上效果图

    image.png
    1.首先准备一些数据

    为了方便的展示ListView(先不care网络请求,网络请求会在下一篇文章中分享) ,我在本地写了一组数据源,使用json格式.
    方法: 在工程目录下新建json格式的文件.

    image.png

    存放这些json数据即可.

    "students":[
      {
        "name":"Jessy",
        "age":"15",
        "sex":"boy",
        "introduce": "My name is Jessy, I like Grassland!",
        "interests": {
          "picture": "http://ojm0517sf.bkt.clouddn.com/1.jpg",
          "profile": "http://ojm0517sf.bkt.clouddn.com/1.jpg",
          "detailed": "http://ojm0517sf.bkt.clouddn.com/1.jpg",
          "original": "http://ojm0517sf.bkt.clouddn.com/1.jpg"
        }
      },
    
      {
        "name":"Lucy",
        "age":"16",
        "sex":"girl",
        "introduce": "My name is Lucy, I like windmill!",
        "interests": {
          "picture": "http://ojm0517sf.bkt.clouddn.com/2.jpg",
          "profile": "http://ojm0517sf.bkt.clouddn.com/2.jpg",
          "detailed": "http://ojm0517sf.bkt.clouddn.com/2.jpg",
          "original": "http://ojm0517sf.bkt.clouddn.com/2.jpg"
        }
      } ...
    
    2.读取本地json数据
    var loadData = require("./Data/studentData.json");
    
    3. 在构造方法中,创建listview
    constructor(props) {
        super(props);
        var listDataSource = new ListView.DataSource({
    /*判断这两行是否相同,是否发生变化,决定渲染哪些行组件,避免全部渲染,提高渲染效率*/  
            rowHasChanged : (oldRow,newRow) => oldRow !== newRow
        });
        this.state = {
            // 将本地数据中的students拷贝至dataSource 中以实例化ListView
    // 我们拷贝的是loadData.students即得到的是students数组
            dataSource: listDataSource.cloneWithRows(loadData.students)
        };
    }
    
    注意以下四点:
    1.ListViewDataSource为ListView组件提供高性能的数据处理与访问。我们需要调用方法从原始输入数据中
    抽取数据,来创建ListViewDataSource对象,
    并用其进行数据变更的比较 (rowHasChanged),原始输入数据可以是简单的字符串数组,也可以是
    复杂嵌套的对象。
    2. rowHasChanged:由ListViewDataSourcey提供,用来判断行内容是否发生变化,如果发生变化,决定
    渲染哪些组件,避免全局渲染造成的效率低下. 
    3.拷贝过程:不使用原始数据,而是使用拷贝后的数据来实例化ListView.如此实现的优点是:
     当原始数据发生变化时,那ListView组件的DataSource不会改变.
    4.设置state属性,这个以后在网络获取的时候如果发生改变,那么ListView也会刷新.
    

    4.ListView的渲染
    渲染ListView需要五个关键步骤:

    • 数据源 dataSource
    • 渲染行 renderRow
    • 渲染头部 renderHeader
    • 渲染分割线 renderSeparator
    • 初始化listView的加载数目 initialListSize
    render() {
        return (
            <ListView
                style = {styles.listView}
                dataSource = {this.state.dataSource}
                renderRow = {_renderRow}
                renderHeader = {_renderHeader}
                renderSeparator = {_renderSeparator}
                initialListSize={10}
            />
        );
    }
    

    分别实现这些渲染方法:

    //渲染行
    function _renderRow(student) {
        return(
            <View style ={styles.row}>
                <Image
                    style = {styles.thumbnail}
                    source ={{uri: student.interests.picture}}
                />
    
                <View>
                    <Text> {student.introduce}</Text>
                    <Text> My age is {student.age}</Text>
                </View>
    
            </View>
        );
    }
    
    // 渲染头部
    function _renderHeader() {
        return(
            <View>
    
               <Text>Students List</Text>
    
            </View>
        );
    }
    // 渲染分割线
    function _renderSeparator(sectionId, rowId) {
        return(
    
                <View style ={styles.separator}
                    key = {sectionId + rowId}>
                </View>
        );
    }
    

    在index页面中引用

    import TestListView from "./TestListView";
    export default class Setup extends Component {
        render() {
            return (
                    <TestListView/>
            );
        }
    }
    
    最后,我们再总结下ListView的实现:
    • 获取数据源(本地数据/网络数据)
    • 使用ListView.DataSource数据源,像其传递一个普通的数组,通过ListViewDataSource的cloneWithRows方法,实现数据拷贝.
      再使用DataSource来实例化一个ListView组件。
    • 设置ListView数据源的时候需要借助state属性
      需要将dataSource对象设置为state属性,那么当数据发生变化的时候,listView也会刷新.
    • listView的渲染renderRow是渲染行renderHeader是渲染头部renderSeparator是渲染分割先initialListSize是设置初始渲染的行数

    献上全局代码:

    
    /***ListView:add by Shmily ****/
    import React, {Component} from 'react';
    import {
            StyleSheet,
            View,
            ListView,
            Image,
            Text
            }
            from 'react-native';
    
    // 读取本地数据
    var loadData = require("./Data/studentData.json");
    
    export default class TestListView extends Component {
        constructor(props) {
            super(props);
            var listDataSource = new ListView.DataSource({
                rowHasChanged : (oldRow,newRow) => oldRow !== newRow
            });
            this.state = {
                // 将本地数据中的movies拷贝至dataSource 中以实例化ListView
                dataSource: listDataSource.cloneWithRows(loadData.students)
            };
        }
    
        render() {
            return (
                <ListView
                    style = {styles.listView}
                    dataSource = {this.state.dataSource}
                    renderRow = {_renderRow}
                    renderHeader = {_renderHeader}
                    renderSeparator = {_renderSeparator}
                    initialListSize={10}
    
                />
            );
        }
    }
    
    //渲染行
    function _renderRow(student) {
        return(
            <View style ={styles.row}>
                <Image
                    style = {styles.thumbnail}
                    source ={{uri: student.interests.picture}}
                />
    
                <View>
                    <Text> {student.introduce}</Text>
                    <Text> My age is {student.age}</Text>
                </View>
    
            </View>
        );
    }
    
    // 渲染头部
    function _renderHeader() {
        return(
            <View>
    
               <Text>Students List</Text>
    
            </View>
        );
    }
    // 渲染分割线
    function _renderSeparator(sectionId, rowId) {
        return(
    
                <View style ={styles.separator}
                    key = {sectionId + rowId}>
                </View>
        );
    }
    
    
    const styles = StyleSheet.create({
        listView: {
            marginTop:25,
            backgroundColor: '#E5ECFF',
        },
    
        row:{
            flexDirection:'row',
            padding:5,
            alignItems:'center',
            backgroundColor:'#F5FCFF',
            padding:15,
            paddingLeft:10,
            paddingTop:10,
            paddingBottom:10,
            paddingRight:15
        },
        thumbnail:{
            width:100,
            height:100,
            backgroundColor:"gray"
        },
        separator:{
            height:1,
            backgroundColor:"black"
        }
    });
    

    相关文章

      网友评论

          本文标题:ReactNative之listView从0到1

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