react-native ListView使用詳解

最近看的RN多了蒙畴,感覺RN寫著比OC寫著舒服多了,對比最強(qiáng)烈的就是布局方面呜象,苦逼的手寫Autolayout代碼膳凝。寫過的肯定懂得,用Frame寫的就不說了...
好的恭陡,廢話不多說蹬音,現(xiàn)在進(jìn)入正題
咱們先看一下官方文檔給的例子
我就直接粘過來了,想深入了解的來戳這里

'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;

對于新手來說是不是有些不理解休玩?沒關(guān)系著淆,我這里帶領(lǐng)大家做一個簡單的ListView,步驟分解一下哥捕。
1.首先引入ListView
這個大家應(yīng)該都會不用我多說了

import React, { Component } from 'react';
import {
  StyleSheet,
  Text,
  View,
ListView
} from 'react-native';
export default class TestDemo extends Component {
  render() {
    return (
      <View style={styles.container}>
        
      </View>
    );
  }
}
const styles = StyleSheet.create({
});

這是我js文件里的代碼牧抽,可能有人問我,看的好多文檔博客都有一句export default XXX 遥赚,為什么你這里沒有呢扬舒?
大家看好,我在申明組件的時候凫佛,在class前面直接加上了export default讲坎,其實(shí)效果一樣的孕惜,對于ES6與ES5的區(qū)別不了解的童鞋,可以看看
論壇 - React Native中文社區(qū)里面的這位大神寫的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>}/>
然后根據(jù)文檔添加數(shù)據(jù)源dataSource
constructor(props){
super(props);
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {dataSource: ds.cloneWithRows([{},])};}
dataSource: ds.cloneWithRows熟悉嗎弥激?看著是什么格式?jsonT覆N⒎!
那么現(xiàn)在來運(yùn)行一下缨历,是不是出現(xiàn)一行的標(biāo)號以蕴?
3.重點(diǎn)來了,怎么自定義Cell靶练酢丛肮?
現(xiàn)在大家可以跟我來做,
我們新做一個組件

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標(biāo)簽換掉。

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

來繼續(xù)運(yùn)行一下徙硅,看看效果榜聂。怎么樣?

這里我是把CellView和ListView放在一個文件里了嗓蘑,有興趣的童鞋可以把它分離出來须肆,肯定特別簡單的。

4.最后怎么能不放上去源碼呢桩皿?

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */

import React, { Component } from 'react';
import {
  StyleSheet,
  Text,
  View,
  ListView,
  Image
} from 'react-native';

export default class TestDemo extends Component {
  constructor(props) {
    super(props);
    const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
    this.state = {
      dataSource: ds.cloneWithRows([
   {logo:'http://upload.jianshu.io/users/upload_avatars/2781235/52637b2553b5.PNG?imageMogr/thumbnail/90x90/quality/100',name:"Demon404"},
{logo:'http://upload.jianshu.io/users/upload_avatars/2781235/52637b2553b5.PNG?imageMogr/thumbnail/90x90/quality/100',name:"Demon404"},
{logo:'http://upload.jianshu.io/users/upload_avatars/2781235/52637b2553b5.PNG?imageMogr/thumbnail/90x90/quality/100',name:"Demon404"},
        ])
    };
  }

  render() {
    return (
      <View style={styles.container}>
        <ListView
          showsVerticalScrollIndicator={false}
          dataSource={this.state.dataSource}
          renderRow={(rowData,rowId) => <CellView source={{uri:rowData.logo}} rowD={rowData.name} />}
        />


      </View>
    );
  }
}



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>
    );
  }
}

const styles = StyleSheet.create({
  container:{
    marginTop:20,
    flex:1,  
    },
});

ps:有的童鞋可能圖片加載不出來豌汇,這是因?yàn)閿?shù)據(jù)源里面的圖片是http鏈接的,iOS需要修改鏈接狀態(tài)泄隔,在Xcode里面修改就可以了拒贱,這里我就不再多做敘述。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市逻澳,隨后出現(xiàn)的幾起案子闸天,更是在濱河造成了極大的恐慌,老刑警劉巖斜做,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件苞氮,死亡現(xiàn)場離奇詭異,居然都是意外死亡瓤逼,警方通過查閱死者的電腦和手機(jī)笼吟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來霸旗,“玉大人赞厕,你說我怎么就攤上這事《ㄏ酰” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵毫目,是天一觀的道長蔬啡。 經(jīng)常有香客問我,道長镀虐,這世上最難降的妖魔是什么箱蟆? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮刮便,結(jié)果婚禮上空猜,老公的妹妹穿的比我還像新娘。我一直安慰自己恨旱,他們只是感情好辈毯,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著搜贤,像睡著了一般谆沃。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上仪芒,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天唁影,我揣著相機(jī)與錄音,去河邊找鬼掂名。 笑死据沈,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的饺蔑。 我是一名探鬼主播锌介,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼膀钠!你這毒婦竟也來了掏湾?” 一聲冷哼從身側(cè)響起裹虫,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎融击,沒想到半個月后筑公,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡尊浪,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年匣屡,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拇涤。...
    茶點(diǎn)故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡捣作,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出鹅士,到底是詐尸還是另有隱情券躁,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布掉盅,位于F島的核電站也拜,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏趾痘。R本人自食惡果不足惜慢哈,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望永票。 院中可真熱鬧卵贱,春花似錦、人聲如沸侣集。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽世分。三九已至方妖,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間罚攀,已是汗流浹背党觅。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留斋泄,地道東北人杯瞻。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像炫掐,于是被迫代替她去往敵國和親魁莉。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容