美文网首页
React Native学习之路(4)-组件篇(ListView

React Native学习之路(4)-组件篇(ListView

作者: woow_wu7 | 来源:发表于2017-07-10 17:55 被阅读61次
    (1) ListView:一个核心组件,用于高效地显示一个可以垂直滚动的变化的数据列表。
    基本语法:
    • dataSource :代表ListView的数据源
    • renderRow :代表渲染的每一行

    (1) dataSource

    • new ListView.DataSource
    • rowHasChanged
    • cloneWithRows
      (1) 如果我们要创建一个数据源,最基本的方法就是创建一个ListView.DataSource数据源,然后通过cloneWithRows方法为其传递一个数组。
      (2) 其中提供给数据源的rowHasChanged函数可以告诉ListView它是否需要重绘一行数据,即数据是否发生了改变,即在需要重绘界面的时候会进行判断,如果之前页面中的改行数据没有发生变化,则不再进行重绘,否则进行重绘。(即比对前后同一条数据是否发生了改变)
    (1-1) dataSource初始化:
    -
     constructor(props) {
          super(props);
          var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
          this.state = {
            dataSource: ds.cloneWithRows(['row 1', 'row 2']),
          };
        }
    
    (1-2) dataSource初始化时,可以定义一个函数在制定数据源。比如下面的:
    -
    dataSource: ds.cloneWithRows(this._genRows())的_genRows函数;
    -
        constructor(props){
            super(props);
            var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
            this.state = {
                dataSource: ds.cloneWithRows(this._genRows()),
            };
        }
        _genRows(){
            const dataBlob = [];
            for(let i = 0 ; i< 200 ; i ++ ){
                dataBlob.push("aa"+i);
            }
            return dataBlob;
        }
    
    (3) dataSource的使用:
    -
    通过dataSource={ this.state.dataSource }来调用
    -
    <ListView
                        dataSource={this.state.dataSource}
                        renderRow={ this._renderRow.bind(this) }
                    />
    

    (2) renderRow

    (1) 该属性需要传入一个方法,该方法如上所示,他会从数据源中接受一条数据,以及他和他所在的section的Id,返回一个可渲染的组件来为这行数据进行渲染,默认情况下参数中的数据就是放进数据源中的数据本身,不过也可以提供一些转换器。
    (2) 如果某一行正在被高亮(通过调用highlightRow函数),ListView会得到相应的通知。当一行被高亮时,其两侧的分割线会被隐藏。行的高亮状态可以通过调用highlightRow(null)来重置。

    _renderRow(rowData, sectionID, rowID){
            return (
                    <View>
                        <Text>{"rowData:"+rowData+"   rowId:"+rowID}</Text>
                    </View>
                );
        }
        render() {
          return (
            <ListView
              dataSource={this.state.dataSource}
              renderRow={this._renderRow}  //注意这里没有括号( (不是this._renderRow) )
            />
          );
        },
    

    完整代码:

    export default class List extends Component {
        constructor(props) {
            super(props);
            var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
            this.state = {
                dataSource: ds.cloneWithRows(this._genRows()),
            };
        }
        _genRows() {
            const data = [];
            for(var i=0; i<100; i++){
                data.push("aa" + i);
            }
            return data;
        };
        _pressRow(rowID){
            alert("这是第"+ rowID + "行");
        };
        _renderRow(rowData, sectionID, rowID) {
            return (
                <TouchableOpacity onPress={()=>this._pressRow(rowID)}>
                    <View>
                        <Text>{"rowData:"+rowData+"   rowId:"+rowID}</Text>
                        <Text style={{backgroundColor:'green'}}>{ rowData}</Text>
                    </View>
                </TouchableOpacity>
            );
        }
        render() {
            return (
                <View style={styles.content}>
                    <View style={ styles.header}>
                        <Text style={styles.headerTitle}>
                            列表页
                        </Text>
                    </View>
                    <ListView
                        dataSource={this.state.dataSource}
                        renderRow={ this._renderRow.bind(this) }
                    />
                </View>
            )
        }
    }
    

    (3)ListView的点击事件:

    TouchableOpacity或者TouchableHighlight
    • 当我们需要给ListView的每一行添加点击事件时,只需要在其外层包裹一层TouchableOpacity或者TouchableHighlight,定义好onPress方法即可。
    • 需要注意的是,在ListView的renderRow属性中调用_renderRow一定要绑定this,否则onPress中的this就会指向错误
       _pressRow(rowID){
            alert("hellow"+rowID);
        }
        _renderRow(rowData, sectionID, rowID){
            return (
                <TouchableOpacity onPress={()=>this._pressRow(rowID)}>
                    <View>
                        <Text>{"rowData:"+rowData+"   rowId:"+rowID}</Text>
                        <Item_MyListView info={rowData}></Item_MyListView>
                    </View>
                </TouchableOpacity>
                );
        }
    
      <ListView dataSource={this.state.dataSource} 
                renderRow={this._renderRow.bind(this)}
    />
    

    (4) Dimensions接口 (dimensions是规格尺寸的意思)

    • (1)引入Dimensions模块api
    • (2)var width = Dimensions.get('window').width;
    • (2)var height = Dimensions.get('window').height;
    • (3)使用: width : width;
    ListView效果图

    完整代码:

    import React, { Component } from 'react';
    import {
        AppRegistry,
        StyleSheet,
        View,
        Text,
        Image,
        ListView,
        TouchableOpacity,
        Dimensions
    }from 'react-native';
    var width = Dimensions.get('window').width;
    // var height = Dimensions.get('window').height;
    export default class List extends Component {
        constructor(props) {
            super(props);
            var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
            this.state = {
                dataSource: ds.cloneWithRows([ {
                    "id": "710000201512201032",
                    "thumb": "http://g1.ykimg.com/050C0000595C3945ADC0AEC7BF085F58",
                    "video": "http://www.imooc.com/static/lib/mocoplayer/2.5.1/mocoplayer.swf?v=2.4.3"
                },
                    {
                        "id": "540000201705130953",
                        "thumb": "http://g1.ykimg.com/050C0000595C3945ADC0AEC7BF085F58",
                        "video": "http://www.imooc.com/static/lib/mocoplayer/2.5.1/mocoplayer.swf?v=2.4.3"
                    },
                    {
                        "id": "36000020090726779X",
                        "thumb": "http://g1.ykimg.com/050C0000595C3945ADC0AEC7BF085F58",
                        "video": "http://www.imooc.com/static/lib/mocoplayer/2.5.1/mocoplayer.swf?v=2.4.3"
                    },
                    {
                        "id": "23000019890819858X",
                        "thumb": "http://g1.ykimg.com/050C0000595C3945ADC0AEC7BF085F58",
                        "video": "http://www.imooc.com/static/lib/mocoplayer/2.5.1/mocoplayer.swf?v=2.4.3"
                    },
                    {
                        "id": "810000199101084138",
                        "thumb": "http://g1.ykimg.com/050C0000595C3945ADC0AEC7BF085F58",
                        "video": "http://www.imooc.com/static/lib/mocoplayer/2.5.1/mocoplayer.swf?v=2.4.3"
                    },
                    {
                        "id": "810000198412233773",
                        "thumb": "http://g1.ykimg.com/050C0000595C3945ADC0AEC7BF085F58",
                        "video": "http://www.imooc.com/static/lib/mocoplayer/2.5.1/mocoplayer.swf?v=2.4.3"
                    },
                    {
                        "id": "610000200610314331",
                        "thumb": "http://g1.ykimg.com/050C0000595C3945ADC0AEC7BF085F58",
                        "video": "http://www.imooc.com/static/lib/mocoplayer/2.5.1/mocoplayer.swf?v=2.4.3"
                    },
                    {
                        "id": "360000201607162472",
                        "thumb": "http://g1.ykimg.com/050C0000595C3945ADC0AEC7BF085F58",
                        "video": "http://www.imooc.com/static/lib/mocoplayer/2.5.1/mocoplayer.swf?v=2.4.3"
                    }
                ]),
            };
        }
        _renderRow(rowData, sectionID, rowID) {
    
            return (
                <TouchableOpacity>
                    <View>
                        <View style={ styles.titleContainer}>
                            <Text style={styles.title}>美女和男神的养成密集,让赵丽颖来告诉你</Text>
                        </View>
    
                        <View>
                            <Image source={{ uri: rowData.thumb }} style={styles.img}></Image>
                            <Image source={ require('../../go.png') } style={styles.go}></Image>
                        </View>
    
                        <View style={styles.bottom}>
                            <View style={styles.bottomBoth}>
                                <Image style={styles.sLogo} source={ require('../../love.png') }></Image>
                                <Text style={ styles.bottomText}>喜欢</Text>
                            </View>
                            <View style={styles.bottomBoth}>
                                <Image style={styles.sLogo2} source={ require('../../discuss.png') }></Image>
                                <Text style={ styles.bottomText}>评论</Text>
                            </View>
                        </View>
    
                    </View>
    
                </TouchableOpacity>
            );
        }
    
        render() {
            return (
                <View style={styles.content}>
                    <View style={ styles.header}>
                        <Text style={styles.headerTitle}>
                            列表页
                        </Text>
                    </View>
    
                    <ListView
                        dataSource={this.state.dataSource}
                        renderRow={ this._renderRow }
                    />
    
                </View>
            )
        }
    }
    
    
    const styles = StyleSheet.create({
        content: {
            flex:1,
            // justifyContent: 'center',
            // alignItems: 'center'
        },
        header: {
            backgroundColor: '#ee735c',
            paddingTop:16,
            paddingBottom:16
        },
        headerTitle: {
            color:'white',
            fontWeight: '600',
            textAlign: 'center',
            fontSize: 18,
            letterSpacing: 300,
        },
        img: {
            width: width,
            height: 300
        },
        go: {
            position: 'absolute',
            width: 50,
            height: 50,
            bottom: 30,
            right:60
        },
        title: {
            fontSize: 20,
            letterSpacing: 18
        },
        titleContainer: {
            height:46,
            marginTop:14
        },
        bottom: {
            height:60,
            paddingBottom:84,
            flexDirection: 'row',
            justifyContent: 'space-between',
            backgroundColor:"#eee"
        },
        bottomBoth: {
            flexDirection: 'row',
            justifyContent: 'center',
            width: width / 2 - 0.5,
            backgroundColor:"white",
            height:70,
            paddingTop: 4,
            alignItems: 'center'
        },
        sLogo: {
            width: 38,
            height:38,
            marginRight: 8
        },
        sLogo2: {
            width: 42,
            height:44,
            marginRight: 8
        },
        bottomText: {
            fontSize: 20
        }
    });
    

    (5) onEndReached:上滑预加载

    (6) onEndReachedThreshold:离底部多高时进行预加载;(threshold:临界值的意思)

    
    <ListView    
       dataSource= { this.state.dataSource }
       renderRow = { this._renderRow }
       onEndReached = { this._fetchMoreData}
       onEndReachedThreshold = { 20 }
    />
    

    相关文章

      网友评论

          本文标题:React Native学习之路(4)-组件篇(ListView

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