ReactNative中使用ListView

作者: 水山一村 | 来源:发表于2017-02-15 16:15 被阅读79次
    1.import添加listview的引用
    import {
        StyleSheet,
        View,
        Text,
         Navigator,
        ListView,
        Image,
        TouchableOpacity,
        ActivityIndicator,
        RefreshControl,
    } from 'react-native';
    
    2.ListView的使用

    ListView组件必须的两个属性是dataSource和renderRow。dataSource是列表的数据源,而renderRow则逐个解析数据源中的数据,然后返回一个设定好格式的组件来渲染。
    在render()中,我们渲染一个ListView,在ListView的属性中,我们指定了dataSource和renderRow,这两个属性分别代表ListView的数据源和渲染的每一行。

    dataSource

    如果我们要创建一个数据源,最基本的方法就是创建一个ListView.DataSource数据源,然后通过cloneWithRows方法为其传递一个数组。
    其中提供给数据源的rowHasChanged函数可以告诉ListView它是否需要重绘一行数据,即数据是否发生了改变,即在需要重绘界面的时候会进行判断,如果之前页面中的改行数据没有发生变化,则不再进行重绘,否则进行重绘。

    renderRow

    (rowData, sectionID, rowID, highlightRow) => renderable
    该属性需要传入一个方法,该方法如上所示,他会从数据源中接受一条数据,以及他和他所在的section的Id,返回一个可渲染的组件来为这行数据进行渲染,默认情况下参数中的数据就是放进数据源中的数据本身,不过也可以提供一些转换器。

    3.其他属性
    initialListSize number :

    指定在组件刚挂载的时候渲染多少行数据。用这个属性来确保首屏显示合适数量的数据,而不是花费太多帧逐步显示出来。

    onChangeVisibleRows function: (visibleRows, changedRows) => void

    当可见的行的集合变化的时候调用此回调函数。visibleRows 以 { sectionID: { rowID: true }}的格式包含了所有可见行,而changedRows 以{ sectionID: { rowID: true | false }}的格式包含了所有刚刚改变了可见性的行,其中如果值为true表示一个行变得可见,而为false表示行刚刚离开可视区域而变得不可见。

    pageSize number :

    每次事件循环(每帧)渲染的行数。

    renderRow function (rowData, sectionID, rowID, highlightRow) => renderable

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

    下面直接贴上Demo代码

    首先是目录结构

    项目目录结构
    service.js
    /*
     * 服务URL
     */
    module.exports = {
      //电影搜索
      movie_search: 'https://api.douban.com/v2/movie/search',
    };
    
    
    Utils.js
    import React, { Component } from 'react';
    /*!
     *
     * Util模块 React Native module
     * 主要提供工具方法
     *
     */
    import Dimensions from 'Dimensions';
    
    import {
      PixelRatio,
      ActivityIndicator
      } from 'react-native';
    
    module.exports = {
      navigationHeight: 44,
      navigationBarBGColor:'#3497FF',
      statusBarHeight: 20,
      /*最小线宽*/
      pixel: 1 / PixelRatio.get(),
    
      /*屏幕尺寸*/
      size: {
        width: Dimensions.get('window').width,
        height: Dimensions.get('window').height
      },
      /**
       * 基于fetch的get方法
       * @method post
       * @param {string} url
       * @param {function} callback 请求成功回调
       */
      get: function(url, successCallback,failCallback){
        fetch(url)
          .then((response) => response.text())
          .then((responseText) => {
            successCallback(JSON.parse(responseText));
          })
          .catch(function(err){
            failCallback(err);
          });
      },
      /*loading效果*/
      loading: <ActivityIndicator animating={true} color="#3E00FF" style={{marginTop:Dimensions.get('window').height/2-50,alignItems: 'center',
        justifyContent: 'center'}} size="large"/>
    };
    
    infoListView.js
    'use strict'
    import React, { Component } from 'react';
    import Util from './common/util' ;
    import ServiceURL from './common/service' ;
    import {
        StyleSheet,
        View,
        Text,
         Navigator,
        ListView,
        Image,
        TouchableOpacity,
        ActivityIndicator,
        RefreshControl,
    } from 'react-native';
    
    export  default class Sample_InfoListView extends Component{
        constructor(props) {
            super(props);
            var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
            this.state = {
               dataSource: ds.cloneWithRows([]),
               keywords: 'BBC',
               show: false,
               isRefreshing: false,
            }
        }
     
      render(){
        return(
            <View style={[styles.flex_1,{marginBottom:10}]}>
            {
              this.state.show ?
                <ListView
                  dataSource={this.state.dataSource}
                  renderRow={this._renderRow}
                  enableEmptySections={true}
                  refreshControl={
                      <RefreshControl
                        refreshing={this.state.isRefreshing}
                        onRefresh={()=>{
                            this.setState({isRefreshing: true});
                        setTimeout(() => {
                          this.setState({
                            isRefreshing: false,
                          });
                        }, 3000);}}
                        tintColor="black"
                        title="Loading..."
                        titleColor="black"
                        colors={['#ff0000', '#00ff00', '#0000ff']}
                        progressBackgroundColor="#ffff00"
                      />
                  }/>
                : Util.loading
            }
            </View>
        );
      }
     
    
      componentDidMount(){
        this._getData();
      }
    
      _changeText(val){
        this.setState({
          keywords: val
        });
      }
    
      _renderRow(row){
        var casts = row.casts;
        var names = [];
        for(var i in casts){
          names.push(casts[i].name);
        }
    
        return (
          <View style={[styles.row,styles.item]}>
            <View>
              <Image style={styles.img} source={{uri: row.images.medium}}/>
            </View>
            <View style={{flex:1}}>
              <Text style={styles.mainTitle} numberOfLines={1}>
                名称:{row.title}
              </Text>
              <Text style={styles.textWitdh} numberOfLines={1}>
                演员:{names}
              </Text>
              <Text style={styles.textWitdh} numberOfLines={1}>
                时间:{row.year}   评分:{row.rating.average}
              </Text>
              <Text style={styles.textWitdh} numberOfLines={1}>
                标签:{row.genres}
              </Text>
            </View>
          </View>
        );
      }
    
      _getData(){
        var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
        var that = this;
        var baseURL = ServiceURL.movie_search + '?count=10&q=' + this.state.keywords;
        this.setState({
          show: false
        });
        Util.get(baseURL, function(data){
          if(!data.subjects || !data.subjects.length){
            return alert('获取数据出错');
          }
          var subjects = data.subjects;
          that.setState({
            dataSource: ds.cloneWithRows(subjects),
            show: true
          });
        }, function(err){
          alert(err);
        });
      }
    
    }
    
    var styles = StyleSheet.create({
      flex_1:{
        flex:1,
        marginTop:60,
      },
      row:{
        flexDirection:'row'
      },
      img:{
        width:80,
        height:110,
        resizeMode: Image.resizeMode.contain
      },
      textWitdh:{
        flex:1,
        marginLeft:15,
      },
      mainTitle:{
         flex:1,
         marginLeft:15,
         fontSize:17,
      },
      item:{
        backgroundColor:'#F1F2F3',
        marginTop:0,
        height:140,
        paddingTop:15,
        paddingBottom:5,
        paddingLeft:10,
        borderBottomWidth:Util.pixel,
        borderTopWidth:Util.pixel,
        borderColor:"#ddd"
      },
      
    });
    

    相关文章

      网友评论

        本文标题:ReactNative中使用ListView

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