React Native實戰(zhàn)開發(fā)6:使用ListView

本教程內容和https://zhiwehu.gitbooks.io/react-native/content/ 同步更新。

使用ListView

在上一節(jié)中庵佣,我們已經通過TextInput將todo item加到了app.state.items中外厂,本節(jié)將討論如何通過ListView來顯示這些todo items旧蛾。

ListView是React Naitve的一個核心組件赏胚,用于高效率的顯示縱向滾動的可變化數據列表。使用ListView一般需要:

  1. 創(chuàng)建一個ListView.DataSource又固,并將列表數據填入。我們一般將這個dataSource放在app的state中煤率,這樣當數據變化時仰冠,app會重新渲染ListView。
  2. 創(chuàng)建一個ListView蝶糯,設置其dataSource屬性為剛剛創(chuàng)建的dataSource洋只,并實現其renderRow方法。

接下來我們通過代碼來實現上面的2點昼捍。

引入ListView

// 引入ListView
import {..., ListView, ...} from "react-native";

創(chuàng)建ListView.DataSource并初始化數據

// 創(chuàng)建ListView.DataSource
// 實現rowHasChanged方法识虚,這里認為只要新老兩條數據不相同即為變化
const ds = new ListView.DataSource({rowHasChanged: (row1, row2) => row1 !== row2});

// 將ListView放在state中,這里使用cloneWithRows方法來從一個空列表克隆數據
this.state = {
  ...
  dataSource: ds.cloneWithRows([])
};

初始化ListView

<ListView
  enableEmptySections
  dataSource={this.state.dataSource}
  renderRow={(item) => {
    return (
      <View key={item.key}>
        <Text>{item.text}</Text>
      </View>
    )
  }}
/>

更新dataSource

我們需要在add item到items的時候妒茬,同時更新dataSource担锤,我們只需要調用this.setState()方法即可。在app.js的handleAddItem方法里更新dataSource

handleAddItem() {
  ...
  const newItems = ...
  // 更新state
  this.setState({
    ...
    dataSource: this.state.dataSource.cloneWithRows(newItems)
  });
}

運行結果如下:

使用新的Row組件

為了以后擴展方便乍钻,我們將創(chuàng)建一個新的Row組件肛循,用于顯示ListView中的每一行數據。

row.js

import React, {Component} from "react";

import {View, Text, StyleSheet} from "react-native";

class Row extends Component {
  render() {
    return (
      <View style={styles.container}>
        <View style={styles.textWrap}>
          <Text style={styles.text}>{this.props.text}</Text>
        </View>
      </View>
    )
  }
}

const styles = StyleSheet.create({
  container: {
    padding: 10,
    flexDirection: "row",
    flex: 1,
    justifyContent: "space-between",
    alignItems: "flex-start"
  },
  textWrap: {
    flex: 1,
    marginHorizontal: 10
  },
  text: {
    fontSize: 24,
    color: "#4d4d4d"
  }
});

export default Row;

更新app.js代碼

在app.js里团赁,更新ListView的代碼如下:

// 引入Keyboard
import {View, Text, StyleSheet, Platform, ListView, Keyboard} from "react-native";

// 引入Row
import Row from "./row";
...

<ListView
  style={styles.list}
  enableEmptySections
  dataSource={this.state.dataSource}
  onScroll={() => Keyboard.dismiss()}
  renderRow={({key, ...value}) => {
    return (
      <Row
        key={key}
        {...value}
      />
    )
  }}
  renderSeparator={(sectionId, rowId) => {
    return <View key={rowId} style={styles.separator}/>
  }}
/>

// ListView的style如下:
...
list: {
  backgroundColor: '#FFF'
},
separator: {
  borderWidth: 1,
  borderColor: "#F5F5F5"
}
...

enableEmptySections育拨,在未來的react native版本中,ListView將默認渲染空section headers欢摄,所以這里設置這個參數熬丧。
onScroll={() => Keyboard.dismiss()}會在ListView手指滾動的時候,將輸入框隱藏起來怀挠,給用戶更好的體驗
({key, ...value})使用ES6的...來將item的屬性動態(tài)的傳給Row組件
renderSeparator用于渲染數據行的間隔橫線

再次運行析蝴,是不是感覺樣式更美觀了呢害捕?


待改進的地方

更新dataSource我們可以寫一個通用的方法,這樣以后在增加闷畸、修改尝盼、刪除以及過濾查詢時都可以很方便的調用

/*
 一個通用的setSource方法,方便調用
 */
setSource(items, itemsDatasource, otherState = {}) {
  this.setState({
    items,
    dataSource: this.state.dataSource.cloneWithRows(itemsDatasource),
    ...otherState
  })
}

這樣我們只需要在調用這個方法來更新state了。

handleAddItem() {
    ...
    // 更新state
    this.setSource(newItems, newItems, {value: ""})
  }

本節(jié)代碼:https://github.com/zhiwehu/todo/tree/listview


  1. React Native實戰(zhàn)開發(fā)1:搭建開發(fā)環(huán)境
  2. React Native實戰(zhàn)開發(fā)2:布局
  3. React Native實戰(zhàn)開發(fā)3:模塊劃分
  4. React Native實戰(zhàn)開發(fā)4:屬性和狀態(tài)
  5. React Native實戰(zhàn)開發(fā)5:使用TextInput
  6. React Native實戰(zhàn)開發(fā)6:使用ListView
  7. React Native實戰(zhàn)開發(fā)7:使用Switch更新todo complete狀態(tài)
  8. React Native實戰(zhàn)開發(fā)8: 刪除todo item
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末佑菩,一起剝皮案震驚了整個濱河市盾沫,隨后出現的幾起案子,更是在濱河造成了極大的恐慌殿漠,老刑警劉巖赴精,帶你破解...
    沈念sama閱讀 221,576評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異绞幌,居然都是意外死亡蕾哟,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 94,515評論 3 399
  • 文/潘曉璐 我一進店門莲蜘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來谭确,“玉大人,你說我怎么就攤上這事票渠≈鸸” “怎么了?”我有些...
    開封第一講書人閱讀 168,017評論 0 360
  • 文/不壞的土叔 我叫張陵庄新,是天一觀的道長鞠眉。 經常有香客問我,道長择诈,這世上最難降的妖魔是什么械蹋? 我笑而不...
    開封第一講書人閱讀 59,626評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮羞芍,結果婚禮上哗戈,老公的妹妹穿的比我還像新娘。我一直安慰自己荷科,他們只是感情好唯咬,可當我...
    茶點故事閱讀 68,625評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著畏浆,像睡著了一般胆胰。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上刻获,一...
    開封第一講書人閱讀 52,255評論 1 308
  • 那天蜀涨,我揣著相機與錄音,去河邊找鬼。 笑死厚柳,一個胖子當著我的面吹牛氧枣,可吹牛的內容都是我干的。 我是一名探鬼主播别垮,決...
    沈念sama閱讀 40,825評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼便监,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了碳想?” 一聲冷哼從身側響起烧董,我...
    開封第一講書人閱讀 39,729評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎移袍,沒想到半個月后解藻,有當地人在樹林里發(fā)現了一具尸體老充,經...
    沈念sama閱讀 46,271評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡葡盗,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,363評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了啡浊。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片觅够。...
    茶點故事閱讀 40,498評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖巷嚣,靈堂內的尸體忽然破棺而出喘先,到底是詐尸還是另有隱情,我是刑警寧澤廷粒,帶...
    沈念sama閱讀 36,183評論 5 350
  • 正文 年R本政府宣布窘拯,位于F島的核電站,受9級特大地震影響坝茎,放射性物質發(fā)生泄漏涤姊。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,867評論 3 333
  • 文/蒙蒙 一嗤放、第九天 我趴在偏房一處隱蔽的房頂上張望思喊。 院中可真熱鬧,春花似錦次酌、人聲如沸恨课。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,338評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽剂公。三九已至,卻和暖如春吊宋,著一層夾襖步出監(jiān)牢的瞬間纲辽,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,458評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留文兑,地道東北人盒刚。 一個月前我還...
    沈念sama閱讀 48,906評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像绿贞,于是被迫代替她去往敵國和親因块。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,507評論 2 359

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,283評論 25 707
  • (一)H5吩愧、React Native、Native應用對比分析 文章來源:@王利華增显,vczerohttp://vc...
    時茶閱讀 10,955評論 2 22
  • React的學習資源 這個文章好久沒有更新了雁佳,資源算比較老舊的了,畢竟前端更新還是非惩疲快的糖权。 半年不學習,都不知道...
    izhongxia閱讀 23,227評論 11 629
  • 或許我們終將老去炸站。 當我們子女成群星澳, 待那時孩孫繞膝, 我會不會已經老到癡呆而忘記許多東西旱易。 忘記我和你的相遇...
    提拉米蘇的貓閱讀 429評論 0 2
  • 我們每個人都是矛盾的個體心俗。沒有意外的話都是這樣麻养。 早上,陽光透過窗簾灑下金黃的余暉,我正在繼續(xù)睡和起床...
    飛青云閱讀 148評論 0 0