最近在學(xué)習(xí)React-Native的ListView組件,其實ListView 相當(dāng)于iOS中的tableview,當(dāng)然也可以通過改變布局來實現(xiàn)collectionView的樣式辈毯,和分組的tableview樣式,下面先看效果圖钝凶。
1唁影,基本ListView布局
第一種ListView布局應(yīng)該是最簡單了耕陷,沒有分組据沈,只要知道ListView的創(chuàng)建方法,和如何設(shè)置
ListView的數(shù)據(jù)源就行了锌介。
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
ListView,
Image} from 'react-native';
var Dimensions = require('Dimensions');//獲取屏幕的寬高
var ScreenWidth = Dimensions.get('window').width;
var ScreenHeight = Dimensions.get('window').height;
var FirstView = React.createClass({
getInitialState(){
var ds = new ListView.DataSource({rowHasChanged:(r1,r2) => r1 !== r2});
return{
dataSource:ds.cloneWithRows(this.getRows({}))//初始化數(shù)據(jù)源
}
},
//制作假數(shù)據(jù)
getRows(){
var dataArr = [];
for (var i = 0; i<100; i++){
dataArr.push({
title: 'Row' + i,
text:'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' + i
} ) }
return dataArr;
},
render(){
return(
// 創(chuàng)建ListView組件
<ListView
dataSource={this.state.dataSource}//設(shè)置數(shù)據(jù)源
renderRow={this.renderRow}//返回cell
/> ) },
//返回cell的方法
renderRow(rowData,sectionID,rowID,highlightRow){
return(
<View style={styles.rightViewStyle}>
<Image style={styles.imageStyle}/>
<View>
<Text style={styles.titleStyle}>{rowData.title}</Text>
<Text style={styles.textStyle}>{rowData.text}</Text>
</View>
</View> ) }})
//樣式
const styles = StyleSheet.create({
tabStyle:{
flex:1
},
rightViewStyle:{
flexDirection:'row',
borderBottomColor:'#CCCCCC',//cell的分割線
borderBottomWidth:1
},
imageStyle:{
width:80,
height:80,
margin:20,
backgroundColor:'red'
},
titleStyle:{
marginTop:20,
backgroundColor:'yellow'
},
textStyle:{
width:ScreenWidth-140,
backgroundColor:'green',
marginBottom:20
}});
module.exports = FirstView;
2孔祸,類似collectionView的布局
改變ListView的主軸方向,讓ListView橫向布局拂蝎,然后設(shè)置換行顯示,就能實現(xiàn)類似
collectionView的布局了
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
ListView, Image} from 'react-native';
var Dimensions = require('Dimensions');//獲取屏幕的寬高
var ScreenWidth = Dimensions.get('window').width;
var ScreenHeight = Dimensions.get('window').height;
var SecondView = React.createClass({
getInitialState(){
//初始化數(shù)據(jù)源
var ds = new ListView.DataSource({rowHasChanged:(r1,r2) => r1 !== r2});
return{
dataSource : ds.cloneWithRows(this.getRows({}))
}
},
//制作假數(shù)據(jù)
getRows(){
var Arr = [];
for(var i = 0; i<100; i++){
Arr.push(
{
image: '111',
price:'222'
} )
}
return Arr;
},
render(){
return(
<ListView //創(chuàng)建ListView
dataSource={this.state.dataSource} //設(shè)置數(shù)據(jù)源
renderRow={this.renderRow} //設(shè)置cell
contentContainerStyle={styles.listViewStyle}//設(shè)置cell的樣式
/>)
},
//返回cell的方法
renderRow(rowData,sectionID,rowID,highlightRow){
return(
<View style={styles.bgStyle}>
<Image style={styles.imageStyle}/>
<Text style={{fontSize:20,marginBottom:0}}>{rowData.price}</Text>
</View> ) }})
//樣式
const styles = StyleSheet.create({
listViewStyle:{
flexDirection:'row', //設(shè)置橫向布局
flexWrap:'wrap' //設(shè)置換行顯示
},
bgStyle:{
backgroundColor:'gray',
width:(ScreenWidth-30)/2, //cell的寬度
height:250,
marginLeft:10,
marginTop:10
},
imageStyle:{
width:(ScreenWidth-30)/2,
height:230,
backgroundColor:'red',
marginBottom:0,
}
});
module.exports = SecondView;
3,分組ListView的布局
因為是分組的ListView,顯然設(shè)置數(shù)據(jù)源的方法就應(yīng)該用cloneWithRowsAndSections
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
ListView,
Image} from 'react-native';
如果不提供針對section標(biāo)題和行數(shù)據(jù)提供自定義的提取方法拇涤,就會使用默認的方法,
var ThirdView = React.createClass({
getInitialState(){
var getSectionData = (dataBlob,sectionID)=>{
return dataBlob[sectionID];
};
var getRowData = (dataBlob,sectionID,rowID) =>{
return dataBlob[sectionID + ':' + rowID];
};
因為這里我們需要返回區(qū)的數(shù)據(jù)券躁,所以我們需要提供方法來提取行數(shù)據(jù)和section標(biāo)題
return{
dataSource:new ListView.DataSource({
getSectionData:getSectionData,
getRowData:getRowData,
rowHasChanged:(r1,r2)=> r1 !==r2,
sectionHeaderHasChanged:(s1,s2)=> s1!== s2 }) }
},
//從上面的圖片我們可以看出提取函數(shù)處理的數(shù)據(jù)的形式掉盅,其實就是個二維數(shù)組,
//制作假數(shù)據(jù)
getLocaData(){
var Arr = {},
sectionIDs =[],//所有區(qū)ID的數(shù)組
rowIDs =[];//行ID數(shù)組
//通過兩次for循環(huán)創(chuàng)建假數(shù)據(jù)
for (var i = 0; i< 10; i++){
sectionIDs.push(i);
Arr[i] = 'section' + i;
rowIDs[i] = [];
for (var j= 0; j<5; j++){
rowIDs[i].push(j);
Arr[i +':' +j] = 'section' + i + '--row' + j;
}
}
//重新設(shè)置ListView的數(shù)據(jù)源趾痘,刷新表
this.setState({
dataSource:this.state.dataSource.cloneWithRowsAndSections(Arr,sectionIDs,rowIDs)
})
},
render(){
return(
<ListView//創(chuàng)建表,并設(shè)置返回section和cell的方法
dataSource={this.state.dataSource}
renderRow={this.renderRow}
renderSectionHeader={this.renderSectionHeader}
contentContainerStyle={styles.listViewStyle} /> )
},
//這個方法相當(dāng)于iOS的viewDidload方法卵贱,通常用于網(wǎng)絡(luò)請求滥沫,返回數(shù)據(jù)之后重新刷新表,這里讓它調(diào)用制作假數(shù)據(jù)的方法键俱,然后刷新表
componentDidMount(){
this.getLocaData();
},
//返回cell的方法
renderRow(rowData,sectionID,rowID,highlighRow){
return(
<View style={styles.cellStyle}>
<Image style={styles.imageStyle}/>
<Text>{rowData}</Text>
</View> )
},
//返回section的方法
renderSectionHeader(sectionData,sectionID){
return(
<View style={styles.sectionStyle}>
<Text>{sectionData}</Text>
</View> ) },})
//樣式
const styles = StyleSheet.create({
sectionStyle:{
backgroundColor:'gray',
height:25
},
cellStyle:{
flexDirection:'row', //設(shè)置橫向布局
borderBottomColor:'#CCCCCC',
borderBottomWidth:1,
alignItems:'center'//交叉軸的對齊方式
},
imageStyle:{
width:70,
height:70,
backgroundColor:'red',
margin:20
},
});
module.exports = ThirdView;
最后的樣子就是下面的圖片,主要要理解ListView的數(shù)據(jù)源的結(jié)構(gòu)缀辩,通過構(gòu)造假數(shù)據(jù)可以更好的理解如何給ListView設(shè)置數(shù)據(jù)源