React Native中ScrollView組件輪播圖與ListView渲染列表組件用法實(shí)例分析
本文實(shí)例講述了React Native中ScrollView組件輪播圖與ListView渲染列表組件用法。分享給大家供大家參考,具體如下:
1、Scroll View
ScrollView是React Native提供的滾動(dòng)視圖組件,渲染一組視圖,用戶可以進(jìn)行滑動(dòng)響應(yīng)交互,其常用屬性如下:
滾動(dòng)的偏移量:通過(guò)event.nativeEvent.contentOffset.x可以得到水平偏移量。
- horizontal={bool},屬性為true時(shí),所有子視圖在水平方向排列,否則在縱向排列。默認(rèn)為false。
- pagingEnabled={bool},屬性為true時(shí),滾動(dòng)會(huì)停留在視圖尺寸整數(shù)倍位置上,即正好顯示某個(gè)視圖,默認(rèn)為false
- scrollEnabled={bool},值為false時(shí),視圖不能滾動(dòng),默認(rèn)true
- showsHorizontalScrollIndicator={bool},值為true在滾動(dòng)時(shí)會(huì)在屏幕底部顯示一個(gè)滾動(dòng)條,默認(rèn)true
- showsVerticalScrollIndicator={bool},值為true在滾動(dòng)時(shí)顯示垂直方向的滾動(dòng)條,默認(rèn)true。
- keyboardDismissMode="none"/"on-drag",滑動(dòng)視圖時(shí)是否隱藏軟鍵盤(pán),默認(rèn)none不隱藏。
- onContentChange={function},當(dāng)ScrollView視圖大小發(fā)生變化時(shí)調(diào)用函數(shù)。
- onScroll={function},當(dāng)滾動(dòng)視圖時(shí)調(diào)用函數(shù)。
- onMomentumScrollStart={function},滾動(dòng)開(kāi)始調(diào)用函數(shù)。
- onMomentumScrollEnd={function},滾動(dòng)結(jié)束時(shí)調(diào)用函數(shù)。
組件所屬的方法有:
- scrollTo({x:num,y:num,animated:bool}),組件視圖滾動(dòng)到指定x,y位置,第三個(gè)參數(shù)為是否啟用動(dòng)畫(huà)
- scrollToEnd({animated:bool}),滾動(dòng)到視圖末尾。
例如利用ScrollView來(lái)實(shí)現(xiàn)一個(gè)Banner輪播:
頁(yè)面結(jié)構(gòu)如下:
<View style={styles.banner}>
<ScrollView ref="scrollView" horizontal={true}
pagingEnabled={true} showsHorizontalScrollIndicator={false}
onMomentumScrollEnd={(e)=>this.slide(e)}
onScrollBeginDrag={()=>{this.stopTimer()}} //用戶拖拽時(shí)停止自動(dòng)輪播
onScrollEndDrag={()=>{this.setTimer()}} //拖拽結(jié)束后開(kāi)始自動(dòng)切換
>
{/*渲染輪播圖片*/}
{this.renderBanner()}
</ScrollView>
<View style={styles.indicateBar}>
{/*渲染底部指示標(biāo)簽點(diǎn)*/}
{this.renderIndicate()}
</View>
</View>
利用map遍歷數(shù)據(jù)數(shù)組zodiac,將圖片渲染到頁(yè)面
renderBanner(){
return zodiac.map((item,index)=>
<Image key={index} source={{uri:'asset:/zodiac/'+item.image+'.jpg'}} style={styles.itemImage} />
)
}
在底部渲染指示點(diǎn):
renderIndicate(){
let jsx=[];
for (let i=0;i<zodiac.length;i++){
//判斷是否為當(dāng)前頁(yè),若為當(dāng)前頁(yè)則指示點(diǎn)color為藍(lán)色,否則為白色
if (i===this.state.pageIndex){
jsx.push(<Text key={i} style={{fontSize:15,color:'#5cb0ff'}}>●</Text>)
}else {
jsx.push(<Text key={i} style={{fontSize:15,color:'#ffffff'}}>●</Text>)
}
}
return jsx;
}
當(dāng)用戶滑動(dòng)結(jié)束時(shí)觸發(fā)ScrollView的onMomentumScrollEnd方法,調(diào)用slide函數(shù),并傳遞event參數(shù)給slide。通過(guò)計(jì)算得出用戶滑到的當(dāng)前頁(yè)的索引pageIndex,其中頁(yè)碼的計(jì)算就是將x偏移量除以每個(gè)視圖的寬度然后取整
slide(e){
let offset=e.nativeEvent.contentOffset.x; //獲取x偏移量
let index=Math.floor(offset/DevWidth); //通過(guò)偏移量計(jì)算出當(dāng)前頁(yè)碼
this.setState({
pageIndex:index
})
}
設(shè)置定時(shí)器讓視圖自動(dòng)更換,通過(guò)setInterval讓pageIndex隔一段時(shí)間自動(dòng)+1,然后讓圖片偏移到頁(yè)碼對(duì)應(yīng)的圖片,令頁(yè)面索引乘以每個(gè)頁(yè)面寬度即為當(dāng)前頁(yè)面對(duì)應(yīng)的偏移量:
setTimer(){
this.timer=setInterval(()=>{
this.setState((preState)=>{ //更新pageIndex
if(preState.pageIndex>=(zodiac.length-1)){ //如果頁(yè)碼達(dá)到上界則歸零
return {pageIndex:0}
}else {
return {pageIndex:preState.pageIndex+1} //否則頁(yè)碼加一
}
});
// 讓圖片偏移到頁(yè)碼所對(duì)應(yīng)的頁(yè)面
let offset=this.state.pageIndex*DevWidth;
this.refs.scrollView.scrollTo({x:offset,y:0,animated:true});
},2000)
}
在組件銷(xiāo)毀時(shí)清除定時(shí)器
componentWillUnmount() {
clearInterval(this.timer);
}
2、List View
<ListView>用于將一組相同類(lèi)型的數(shù)據(jù)渲染到頁(yè)面上,你只需要定義好數(shù)據(jù)源與單個(gè)組件如何渲染,它便會(huì)將所有數(shù)據(jù)渲染完成。例如將如下左邊json數(shù)據(jù)渲染為右邊icon列表:
使用步驟如下
1、定義數(shù)據(jù)源,在constructor中初始化state,創(chuàng)建一個(gè)DataSource對(duì)象,在state中定義數(shù)據(jù)源iconSource為外部導(dǎo)入的json數(shù)據(jù)icons,格式如下:
let icons=require('./mockdata/icons.json').data;
constructor(props){
super(props);
let dataSource = new ListView.DataSource({rowHasChanged:(r1,r2)=>r1!==r2});
this.state={
iconSource:dataSource.cloneWithRows(icons),
}
}
其中{rowHasChaged:(r1,r2)=>r1!==r2},是告訴ListView當(dāng)數(shù)據(jù)源變化時(shí)再重新渲染。
2、在頁(yè)面使用<ListView>,設(shè)置數(shù)據(jù)源dataSource,內(nèi)部樣式contentContainerStyle,每個(gè)元素的渲染方式renderRow為renderIcon
<ListView dataSource={this.state.iconSource} contentContainerStyle={styles.iconList}
renderRow={this.renderIcon}
/>
3、實(shí)現(xiàn)渲染函數(shù)renderIcon,默認(rèn)傳入四個(gè)參數(shù):
- rowData:每個(gè)元素對(duì)應(yīng)的數(shù)據(jù)
- sectionId:元素所屬分區(qū)
- rowId:元素的id
- highlightRow:通過(guò)調(diào)用此方法可以使某一行處于高亮
在renderIcon函數(shù)中定義每一個(gè)icon圖標(biāo)的渲染的方式,并返回JSX:
renderIcon(rowData,sectionId,rowId,highlightRow){
return(
<TouchableOpacity activeOpacity={0.5}>
<View key={rowId} style={styles.iconItem}>
<Image style={styles.iconImg} source={{uri:'mipmap/'+rowData.image}} />
<Text style={styles.iconTitle}>{rowData.title}</Text>
</View>
</TouchableOpacity>
)
}
3、使用ListView渲染二維數(shù)據(jù)
以上例子中的data是個(gè)一維數(shù)組,數(shù)組每個(gè)元素中包含title與image兩個(gè)字段,如果data是個(gè)二維數(shù)組,例如
其中data數(shù)組的一維元素中包含title與cars,而cars又是一個(gè)數(shù)組。使用ListView將其渲染為上面右圖所示按首字母分類(lèi)的列表。
存儲(chǔ)原理:
ListView使用DataBlob來(lái)存儲(chǔ)二維數(shù)據(jù),其結(jié)構(gòu)如下:
DataBlob按照一定的格式組織二維數(shù)據(jù),如上左圖。DataBlob首先存儲(chǔ)數(shù)組的第一維section并為其分配ID,例如將上面的一維數(shù)組的"title":"A",存儲(chǔ)為DataBlob[0]="title":"A",分配sectionID為0,"title":"B",存儲(chǔ)為DataBlob[1]="title":"B",分配ID為1......以此類(lèi)推。
之后再存儲(chǔ)數(shù)組的第二維row,例如"cars":[{"name":"奧迪","icon": "m_9_100.png"}],它的第一維sectionID為0,第二維rowID為2,將其存儲(chǔ)為DataBlob[0:2]={"name":"奧迪","icon": "m_9_100.png"}。
ListView使用步驟如下:
1、設(shè)置數(shù)據(jù)源
與一維ListView使用類(lèi)似,首先在constructor中設(shè)置state為DataSource對(duì)象:
this.state={
carData:new ListView.DataSource({
getSectionData:(dataBlob,sectionID)=>dataBlob[sectionID], //設(shè)置sectionData獲取方式
getRowData:(dataBlob,sectionID,rowID)=>dataBlob[sectionID+':'+rowID], //設(shè)置rowData獲取方式
sectionHeaderHasChanged:(s1,s2)=>s1!==s2, //設(shè)置section更新方式
rowHasChanged:(r1,r2)=>r1!==r2 //設(shè)置row更新方式
})
}
在新建DataSource對(duì)象時(shí)需要傳遞四個(gè)函數(shù)參數(shù)
- getSectionData:定義獲取section的方式,它接收兩個(gè)參數(shù),dataBlob對(duì)象與sectionId,例如要獲取上面提到的DataBlob[0]="title":"A" ,則通過(guò)dataBlob[sectionID]就可以返回"title":"A"。
- getRowData:獲取row的方式,同理,通過(guò)DataBlob[0:2]可以得到{"name":"奧迪","icon": "m_9_100.png"}
- sectionHeaderHasChanged:定義section什么時(shí)候更新,接收兩個(gè)參數(shù)s1,s2分別為前后兩個(gè)狀態(tài),不同時(shí)才會(huì)重新渲染section
- rowHasChanged:定義row什么時(shí)候更新
2、在頁(yè)面中使用ListView
使用List View時(shí)設(shè)置其數(shù)據(jù)源及渲染方法
<ListView style={styles.carList}
dataSource={this.state.carData} //定義數(shù)據(jù)源
renderRow={this.renderCarRow} //定義row的渲染方法
renderSectionHeader={this.renderCarSection} //定義SectionHeader渲染方法
/>
3、實(shí)現(xiàn)渲染方法,方法默認(rèn)會(huì)傳入?yún)?shù)rowData與sectionData
renderCarSection(sectionData){
return(
<View style={styles.sectionBar}>
<Text style={styles.sectionTxt}>{sectionData}</Text>
</View>
)
}
renderCarRow(rowData){
return(
<TouchableOpacity activeOpacity={0.5}>
<View style={styles.carItem}>
<Image source={{uri:'asset:/cars/'+rowData.icon}} style={styles.carImg} />
<Text style={styles.carTitle}>{rowData.name}</Text>
</View>
</TouchableOpacity>
)
}
4、將數(shù)據(jù)放入dataBlob
在組件掛載完成后將數(shù)據(jù)按照格式放入dataBlob并更新數(shù)據(jù)源,使數(shù)據(jù)加載到頁(yè)面
componentDidMount() {
this.loadCarData();
}
loadCarData(){
let dataBlob={}, //dataBlob對(duì)象
sectionIDs=[], //sectionID數(shù)組
rowIDs=[], //rowID數(shù)組
cars=[];
for (let i=0;i<carData.length;i++){ //循環(huán)遍歷二維數(shù)據(jù)carData
sectionIDs.push(i); //將一維下標(biāo)i當(dāng)作sectionID
dataBlob[i]=carData[i].title; //將section數(shù)據(jù)放入dataBlob第一維
rowIDs[i]=[]; //初始化rowID數(shù)組的每個(gè)元素為一個(gè)數(shù)組
cars=carData[i].cars; //拿到每個(gè)section下的cars數(shù)組
for (let j=0;j<cars.length;j++){ //遍歷section下的cars數(shù)組
rowIDs[i].push(j); //二維數(shù)組rowIDs[i][j]
dataBlob[i+':'+j]=cars[j]; //將每行row數(shù)據(jù)放入dataBlob[i:j]第二維
}
}
this.setState({ //更新state中的數(shù)據(jù)源carData,需要傳入三個(gè)參數(shù)
carData:this.state.carData.cloneWithRowsAndSections(dataBlob,sectionIDs,rowIDs)
})
}
希望本文所述對(duì)大家React程序設(shè)計(jì)有所幫助。
欄 目:JavaScript
本文標(biāo)題:React Native中ScrollView組件輪播圖與ListView渲染列表組件用法實(shí)例分析
本文地址:http://www.jygsgssxh.com/a1/JavaScript/9271.html
您可能感興趣的文章
- 04-02javascript匿名,js匿名方法
- 04-02java中間代碼生成器 java自動(dòng)生成代碼工具
- 01-10在Vue項(xiàng)目中使用Typescript的實(shí)現(xiàn)
- 01-10Vue中使用Lodop插件實(shí)現(xiàn)打印功能的簡(jiǎn)單方法
- 01-105分鐘快速看懂ES6中的反射與代理
- 01-10React 實(shí)現(xiàn)車(chē)牌鍵盤(pán)的示例代碼
- 01-10vue中根據(jù)時(shí)間戳判斷對(duì)應(yīng)的時(shí)間(今天 昨天 前天)
- 01-10JavaScript中的相等操作符使用詳解
- 01-10javascript中的相等操作符(==與===區(qū)別)
- 01-10vue實(shí)現(xiàn)拖拽效果


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹(shù)的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 04-02javascript點(diǎn)線,點(diǎn)線的代碼
- 04-02javascript潛力,javascript強(qiáng)大嗎
- 04-02javascript替換字符串,js字符串的替換
- 04-02javascript移出,js 移入移出
- 04-02包含javascript舍的詞條
- 04-02javascript并行,深入理解并行編程 豆瓣
- 04-02javascript匿名,js匿名方法
- 04-02javascript警報(bào),JavaScript警告
- 04-02javascript遮蓋,JavaScript遮蓋PC端頁(yè)面
- 04-02javascript前身,javascript的前身
隨機(jī)閱讀
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 01-10delphi制作wav文件的方法
- 01-11Mac OSX 打開(kāi)原生自帶讀寫(xiě)NTFS功能(圖文
- 01-10C#中split用法實(shí)例總結(jié)
- 04-02jquery與jsp,用jquery
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 01-10SublimeText編譯C開(kāi)發(fā)環(huán)境設(shè)置
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改


