react-native ListView使用详解

恰好今天七夕,呆萌的程序猿没有妹纸,恰好发小明天结婚,我还在异地,晚上还要苦逼的赶火车。趁着下午比较闲,更新一下Blog,也算是在百无聊赖之时给众多单身程序猿们的小福利吧,虽然已经很久没更了...囧html

前面说过,我是作iOS的,可是最近看的RN多了,感受RN写着比OC写着舒服多了,对比最强烈的就是布局方面,苦逼的手写Autolayout代码。写过的确定懂得,用Frame写的就不说了...react

好的,废话很少说,如今进入正题git

我们先看一下官方文档给的例子

我就直接粘过来了,想深刻了解的来戳这里es6

'use strict';

var React = require('react');
var ReactNative = require('react-native');
var {
  Image,
  ListView,
  TouchableHighlight,
  StyleSheet,
  RecyclerViewBackedScrollView,
  Text,
  View,
} = ReactNative;

var UIExplorerPage = require('./UIExplorerPage');

var ListViewSimpleExample = React.createClass({
  statics: {
    title: '<ListView>',
    description: 'Performant, scrollable list of data.'
  },

  getInitialState: function() {
    var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
    return {
      dataSource: ds.cloneWithRows(this._genRows({})),
    };
  },

  _pressData: ({}: {[key: number]: boolean}),

  componentWillMount: function() {
    this._pressData = {};
  },

  render: function() {
    return (
      <UIExplorerPage
        title={this.props.navigator ? null : '<ListView>'}
        noSpacer={true}
        noScroll={true}>
        <ListView
          dataSource={this.state.dataSource}
          renderRow={this._renderRow}
          renderScrollComponent={props => <RecyclerViewBackedScrollView {...props} />}
          renderSeparator={this._renderSeparator}
        />
      </UIExplorerPage>
    );
  },

  _renderRow: function(rowData: string, sectionID: number, rowID: number, highlightRow: (sectionID: number, rowID: number) => void) {
    var rowHash = Math.abs(hashCode(rowData));
    var imgSource = THUMB_URLS[rowHash % THUMB_URLS.length];
    return (
      <TouchableHighlight onPress={() => {
          this._pressRow(rowID);
          highlightRow(sectionID, rowID);
        }}>
        <View>
          <View style={styles.row}>
            <Image style={styles.thumb} source={imgSource} />
            <Text style={styles.text}>
              {rowData + ' - ' + LOREM_IPSUM.substr(0, rowHash % 301 + 10)}
            </Text>
          </View>
        </View>
      </TouchableHighlight>
    );
  },

  _genRows: function(pressData: {[key: number]: boolean}): Array<string> {
    var dataBlob = [];
    for (var ii = 0; ii < 100; ii++) {
      var pressedText = pressData[ii] ? ' (pressed)' : '';
      dataBlob.push('Row ' + ii + pressedText);
    }
    return dataBlob;
  },

  _pressRow: function(rowID: number) {
    this._pressData[rowID] = !this._pressData[rowID];
    this.setState({dataSource: this.state.dataSource.cloneWithRows(
      this._genRows(this._pressData)
    )});
  },

  _renderSeparator: function(sectionID: number, rowID: number, adjacentRowHighlighted: bool) {
    return (
      <View
        key={`${sectionID}-${rowID}`}
        style={{
          height: adjacentRowHighlighted ? 4 : 1,
          backgroundColor: adjacentRowHighlighted ? '#3B5998' : '#CCCCCC',
        }}
      />
    );
  }
});

var THUMB_URLS = [
  require('./Thumbnails/like.png'),
  require('./Thumbnails/dislike.png'),
  require('./Thumbnails/call.png'),
  require('./Thumbnails/fist.png'),
  require('./Thumbnails/bandaged.png'),
  require('./Thumbnails/flowers.png'),
  require('./Thumbnails/heart.png'),
  require('./Thumbnails/liking.png'),
  require('./Thumbnails/party.png'),
  require('./Thumbnails/poke.png'),
  require('./Thumbnails/superlike.png'),
  require('./Thumbnails/victory.png'),
  ];
var LOREM_IPSUM = 'Lorem ipsum dolor sit amet, ius ad pertinax oportere accommodare, an vix civibus corrumpit referrentur. Te nam case ludus inciderint, te mea facilisi adipiscing. Sea id integre luptatum. In tota sale consequuntur nec. Erat ocurreret mei ei. Eu paulo sapientem vulputate est, vel an accusam intellegam interesset. Nam eu stet pericula reprimique, ea vim illud modus, putant invidunt reprehendunt ne qui.';

/* eslint no-bitwise: 0 */
var hashCode = function(str) {
  var hash = 15;
  for (var ii = str.length - 1; ii >= 0; ii--) {
    hash = ((hash << 5) - hash) + str.charCodeAt(ii);
  }
  return hash;
};

var styles = StyleSheet.create({
  row: {
    flexDirection: 'row',
    justifyContent: 'center',
    padding: 10,
    backgroundColor: '#F6F6F6',
  },
  thumb: {
    width: 64,
    height: 64,
  },
  text: {
    flex: 1,
  },
});

module.exports = ListViewSimpleExample;
View Code

 是否是感受有些杂乱的感受?不要紧,我这里带领你们嘴一个简单的ListView,步骤分解一下。github

1.首先引入ListView

这个你们应该都会不用我多说了,json

import React, { Component } from 'react';
import {
StyleSheet,
Text,
View,vim

ListView
} from 'react-native';react-native

export default class TestDemo extends Component {
render() {
return (
<View style={styles.container}>

</View>
);
}
}api

const styles = StyleSheet.create({ide

});

这是我js文件里的代码,可能有人问我,看的好多文档博客都有一句export default XXX  ,为何你这里没有呢?

你们看好,我在申明组件的时候,在class前面直接加上了export default,其实效果同样的,对于ES6与ES5的区别不了解的童鞋,能够看看

论坛 - React Native中文社区里面的这位大神写的React/React Native 的ES5 ES6写法对照表

另外,我们也把StyleSheet也写上,const styles = StyleSheet.create({});

2.开始添加ListView

首先咱么先添加一个背景,

<View style={styles.container}></View>

给他添加样式,flex:1,   以后,咱们开始添加ListView,该怎么添加呢?

<ListView
showsVerticalScrollIndicator={false}
dataSource={this.state.dataSource}
renderRow={(rowData,rowId) => <Text>{rowId}</Text>}
/>

而后根据文档添加数据源dataSource

constructor(props) {
super(props);
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {
dataSource: ds.cloneWithRows([
{

},
])
};
}

dataSource: ds.cloneWithRows熟悉吗?看着是什么格式?json!!!

那么如今来运行一下,是否是出现一行的标号?

不要紧,咱们如今,来模拟一下数据源,想试试的能够直接复制粘贴试试,这是我从一个帖子的抓取的接口获得的数据,具体我也忘了哪一个帖子,有知道的能够私信我加上!是一个球队的接口,接口我也忘了...

我把数据源放在这里:

数据源

那么如今把数据源导进去看一下,而后是否是出现了好多行?咱们把Text中间的rowId改变一下,改为rowData.team_cn,运行一下,看出现了什么!是否是有点挤?不要紧,咱们改变一下style就能够了。

3.重点来了,怎么自定义Cell啊?

如今你们能够跟我来作,

咱们新作一个组件

class CellView extends Component {
render(){
return(
<View style={{height:60,alignItems: 'center',flexDirection:'row',borderBottomWidth:0.5,borderBottomColor:'gray'}}>

<Image source={this.props.source}
style={{width: 40, height: 40}} />
<Text>{this.props.rowD}</Text>

</View>
);
}
}

这是什么组件?头像和名称!经常使用的组件,你们确定不陌生。

那么怎么使用呢?

咱么把Text标签换掉。

换成<CellView source={{uri:rowData.logo}} rowD={rowData.team_cn} />

来继续运行一下,看看效果。怎么样?

这里我是把CellView和ListView放在一个文件里了,有兴趣的童鞋能够把它分离出来,确定特别简单的。

4.最后怎么能不放上去源码呢?

 1 /**
 2  * Sample React Native App
 3  * https://github.com/facebook/react-native
 4  * @flow
 5  */
 6 
 7 import React, { Component } from 'react';
 8 import {
 9   StyleSheet,
10   Text,
11   View,
12   ListView,
13   Image
14 } from 'react-native';
15 
16 export default class TestDemo extends Component {
17   constructor(props) {
18     super(props);
19     const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
20     this.state = {
21       dataSource: ds.cloneWithRows([
22           //这里能够添加数据源,你能够把上面的数据源直接粘贴一下试试手。
23         ])
24     };
25   }
26 
27   render() {
28     return (
29       <View style={styles.container}>
30         <ListView
31           showsVerticalScrollIndicator={false}
32           dataSource={this.state.dataSource}
33           renderRow={(rowData,rowId) => <CellView source={{uri:rowData.logo}} rowD={rowData.team_cn} />}
34         />
35 
36 
37       </View>
38     );
39   }
40 }
41 
42 
43 
44 class CellView extends Component {
45   render(){
46     return(
47       <View style={{height:60,alignItems: 'center',flexDirection:'row',borderBottomWidth:0.5,borderBottomColor:'gray'}}>
48         
49         <Image source={this.props.source}
50                style={{width: 40, height: 40}} />
51         <Text>{this.props.rowD}</Text>
52         
53       </View>
54     );
55   }
56 }
57 
58 const styles = StyleSheet.create({
59   container:{
60     marginTop:20,
61     flex:1,  
62     },
63 });

ps:有的童鞋可能图片加载不出来,这是由于数据源里面的图片是http连接的,iOS须要修改连接状态,在Xcode里面修改就能够了,这里我就再也不多作叙述。

相关文章
相关标签/搜索