ReactNative列表ListView的用法
最近在學(xué)習(xí)ReactNative,本文介紹了ReactNative列表ListView的用法,分享給大家,也給自己留個筆記
ListView
在Android中,如果我們需要顯示一個ListView,有兩項(xiàng)是比不可少的,首先是ListView的數(shù)據(jù)源,其次是ListView每個item的樣式。ReactNative中一樣。首先我們來看一個簡單的例子:
constructor(props) {
super(props);
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {
dataSource: ds.cloneWithRows(['row 1', 'row 2']),
};
},
render() {
return (
<ListView
dataSource={this.state.dataSource}
renderRow={(rowData) => <Text>{rowData}</Text>}
/>
);
},
在render()中,我們渲染一個ListView,在ListView的屬性中,我們指定了dataSource和renderRow,這兩個屬性分別代表ListView的數(shù)據(jù)源和渲染的每一行。
dataSource
如果我們要創(chuàng)建一個數(shù)據(jù)源,最基本的方法就是創(chuàng)建一個ListView.DataSource數(shù)據(jù)源,然后通過cloneWithRows方法為其傳遞一個數(shù)組。
其中提供給數(shù)據(jù)源的rowHasChanged函數(shù)可以告訴ListView它是否需要重繪一行數(shù)據(jù),即數(shù)據(jù)是否發(fā)生了改變,即在需要重繪界面的時候會進(jìn)行判斷,如果之前頁面中的改行數(shù)據(jù)沒有發(fā)生變化,則不再進(jìn)行重繪,否則進(jìn)行重繪。
如上述代碼,我們對數(shù)據(jù)源設(shè)置數(shù)據(jù)時直接傳入一個數(shù)組,當(dāng)然我們也可以通過一個獲取數(shù)據(jù)的方法,在設(shè)置數(shù)據(jù)的時候調(diào)用方法即可:
constructor(props){
super(props);
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {
dataSource: ds.cloneWithRows(this._genRows()),
};
}
_genRows(){
const dataBlob = [];
for(let i = 0 ; i< 200 ; i ++ ){
dataBlob.push("aa"+i);
}
return dataBlob;
}
這樣通過方法獲取數(shù)據(jù),方便我們進(jìn)行一些邏輯的處理。
renderRow
(rowData, sectionID, rowID, highlightRow) => renderable
該屬性需要傳入一個方法,該方法如上所示,他會從數(shù)據(jù)源中接受一條數(shù)據(jù),以及他和他所在的section的Id,返回一個可渲染的組件來為這行數(shù)據(jù)進(jìn)行渲染,默認(rèn)情況下參數(shù)中的數(shù)據(jù)就是放進(jìn)數(shù)據(jù)源中的數(shù)據(jù)本身,不過也可以提供一些轉(zhuǎn)換器。
如果某一行正在被高亮(通過調(diào)用highlightRow函數(shù)),ListView會得到相應(yīng)的通知。當(dāng)一行被高亮?xí)r,其兩側(cè)的分割線會被隱藏。行的高亮狀態(tài)可以通過調(diào)用highlightRow(null)來重置。
_renderRow(rowData, sectionID, rowID){
return (
<View>
<Text>{"rowData:"+rowData+" rowId:"+rowID}</Text>
</View>
);
}
render() {
return (
<ListView
dataSource={this.state.dataSource}
renderRow={this._renderRow}
/>
);
},
因?yàn)閞enderRow中的方法會自動接受從數(shù)據(jù)源中的一條數(shù)據(jù),因此我們可以通過調(diào)用外部方法的方式進(jìn)行實(shí)現(xiàn),同時只需要在外部方法的參數(shù)中傳入我們需要從數(shù)據(jù)源中獲取的數(shù)據(jù)即可,如上代碼所示。
當(dāng)我們需要實(shí)現(xiàn)比較復(fù)雜的布局時,也可以通過導(dǎo)入外部組件的方式作為ListView的每一行的樣式。
例如我們自定義了一個組件Item_MyListView,我們需要在文件開頭通過import方式將其導(dǎo)入到當(dāng)前組件中:
import Item_MyListView from './Item_MyListView';
然后就可以通過導(dǎo)入的名稱直接使用我們導(dǎo)入的組件了:
_renderRow(rowData, sectionID, rowID){
return (
<TouchableOpacity onPress={this._pressRow}>
<View>
<Text>{"rowData:"+rowData+" rowId:"+rowID}</Text>
<Item_MyListView></Item_MyListView>
</View>
</TouchableOpacity>
);
}
ListView的點(diǎn)擊
當(dāng)我們需要給ListView的每一行添加點(diǎn)擊事件時,只需要在其外層包裹一層TouchableOpacity或者TouchableHighlight,定義好onPress方法即可。
如下代碼所示:
_pressRow(rowID){
alert("hellow"+rowID);
}
_renderRow(rowData, sectionID, rowID){
return (
<TouchableOpacity onPress={()=>this._pressRow(rowID)}>
<View>
<Text>{"rowData:"+rowData+" rowId:"+rowID}</Text>
<Item_MyListView info={rowData}></Item_MyListView>
</View>
</TouchableOpacity>
);
}
需要注意的是,在ListView的renderRow屬性中調(diào)用_renderRow一定要綁定this,否則onPress中的this就會指向錯誤,如下所示:
<ListView dataSource={this.state.dataSource} renderRow={this._renderRow.bind(this)}/>
完整代碼如下所示:
import React,{
View,
Text,
TouchableOpacity,
ListView,
} from 'react-native';
import Item_MyListView from './Item_MyListView';
export default class SecondPageComponent extends React.Component{
constructor(props){
super(props);
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {
dataSource: ds.cloneWithRows(this._genRows()),
};
}
_genRows(){
const dataBlob = [];
for(let i = 0 ; i< 200 ; i ++ ){
dataBlob.push("aa"+i);
}
return dataBlob;
}
_pressRow(rowID){
alert("hellow"+rowID);
}
_renderRow(rowData, sectionID, rowID){
return (
<TouchableOpacity onPress={()=>this._pressRow(rowID)}>
<View>
<Text>{"rowData:"+rowData+" rowId:"+rowID}</Text>
<Item_MyListView info={rowData}></Item_MyListView>
</View>
</TouchableOpacity>
);
}
render(){
return (
<View style={{flex:1,}}>
<ListView dataSource={this.state.dataSource} renderRow={this._renderRow.bind(this)}/>
</View>
);
}
}
其中Item_MyListView只是隨意定義了一個組件,沒什么實(shí)際意義,就不再展示。
最終效果如下圖所示:

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
新建的React Native就遇到vscode報(bào)警解除方法
這篇文章主要為大家介紹了新建的React Native就遇到vscode報(bào)警解除方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10
react框架next.js學(xué)習(xí)之API?路由篇詳解
這篇文章主要為大家介紹了react框架next.js學(xué)習(xí)之API?路由篇詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09
React?Native?中處理?Android?手機(jī)吞字的解決方案
這篇文章主要介紹了React?Native?中處理?Android?手機(jī)吞字的解決方案,作者在 React Native 0.67.4 環(huán)境下,編寫了一個小 demo 來復(fù)現(xiàn)這個問題,需要的朋友可以參考下2022-08-08

