ReactNative中使用ListView

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

推荐阅读更多精彩内容

  • 前言 学习本系列内容需要具备一定 HTML 开发基础,没有基础的朋友可以先转至 HTML快速入门(一) 学习 本人...
    珍此良辰阅读 13,339评论 11 24
  • 一. 简介 一个核心组件,用于高效地显示一个可以垂直滚动的变化的数据列表。最基本的使用方式就是创建一个ListVi...
    飞奔的小马阅读 1,238评论 0 2
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,070评论 25 707
  • https是加密的http协议,通过不对称加密确认对称加密的密钥,之后使用对称加密进行通信。通信流程: http ...
    一路摇到顶阅读 1,122评论 0 0
  • 都是单翼的天使,一只翅膀或许可以飞翔,但并不美丽,飞久了,会变坚强,会变深刻。然并卵,很多事情一个人是不能完成的,...
    super丶影弟阅读 167评论 0 0