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裏面修改就能夠了,這裏我就再也不多作敘述。

相關文章
相關標籤/搜索