本文實例講述了React Native中ScrollView組件輪播圖與ListView渲染列表組件用法。分享給大家供大家參考,具體如下:
成都創(chuàng)新互聯(lián)從2013年創(chuàng)立,先為千山等服務(wù)建站,千山等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為千山企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。
ScrollView是React Native提供的滾動視圖組件,渲染一組視圖,用戶可以進(jìn)行滑動響應(yīng)交互,其常用屬性如下:
滾動的偏移量:通過event.nativeEvent.contentOffset.x可以得到水平偏移量。
組件所屬的方法有:
例如利用ScrollView來實現(xiàn)一個Banner輪播:
頁面結(jié)構(gòu)如下:
<View style={styles.banner}> <ScrollView ref="scrollView" horizontal={true} pagingEnabled={true} showsHorizontalScrollIndicator={false} onMomentumScrollEnd={(e)=>this.slide(e)} onScrollBeginDrag={()=>{this.stopTimer()}} //用戶拖拽時停止自動輪播 onScrollEndDrag={()=>{this.setTimer()}} //拖拽結(jié)束后開始自動切換 > {/*渲染輪播圖片*/} {this.renderBanner()} </ScrollView> <View style={styles.indicateBar}> {/*渲染底部指示標(biāo)簽點*/} {this.renderIndicate()} </View> </View>
利用map遍歷數(shù)據(jù)數(shù)組zodiac,將圖片渲染到頁面
renderBanner(){ return zodiac.map((item,index)=> <Image key={index} source={{uri:'asset:/zodiac/'+item.image+'.jpg'}} style={styles.itemImage} /> ) }
在底部渲染指示點:
renderIndicate(){ let jsx=[]; for (let i=0;i<zodiac.length;i++){ //判斷是否為當(dāng)前頁,若為當(dāng)前頁則指示點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)用戶滑動結(jié)束時觸發(fā)ScrollView的onMomentumScrollEnd方法,調(diào)用slide函數(shù),并傳遞event參數(shù)給slide。通過計算得出用戶滑到的當(dāng)前頁的索引pageIndex,其中頁碼的計算就是將x偏移量除以每個視圖的寬度然后取整
slide(e){ let offset=e.nativeEvent.contentOffset.x; //獲取x偏移量 let index=Math.floor(offset/DevWidth); //通過偏移量計算出當(dāng)前頁碼 this.setState({ pageIndex:index }) }
設(shè)置定時器讓視圖自動更換,通過setInterval讓pageIndex隔一段時間自動+1,然后讓圖片偏移到頁碼對應(yīng)的圖片,令頁面索引乘以每個頁面寬度即為當(dāng)前頁面對應(yīng)的偏移量:
setTimer(){ this.timer=setInterval(()=>{ this.setState((preState)=>{ //更新pageIndex if(preState.pageIndex>=(zodiac.length-1)){ //如果頁碼達(dá)到上界則歸零 return {pageIndex:0} }else { return {pageIndex:preState.pageIndex+1} //否則頁碼加一 } }); // 讓圖片偏移到頁碼所對應(yīng)的頁面 let offset=this.state.pageIndex*DevWidth; this.refs.scrollView.scrollTo({x:offset,y:0,animated:true}); },2000) }
在組件銷毀時清除定時器
componentWillUnmount() { clearInterval(this.timer); }
<ListView>用于將一組相同類型的數(shù)據(jù)渲染到頁面上,你只需要定義好數(shù)據(jù)源與單個組件如何渲染,它便會將所有數(shù)據(jù)渲染完成。例如將如下左邊json數(shù)據(jù)渲染為右邊icon列表:
使用步驟如下
1、定義數(shù)據(jù)源,在constructor中初始化state,創(chuàng)建一個DataSource對象,在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ù)源變化時再重新渲染。
2、在頁面使用<ListView>,設(shè)置數(shù)據(jù)源dataSource,內(nèi)部樣式contentContainerStyle,每個元素的渲染方式renderRow為renderIcon
<ListView dataSource={this.state.iconSource} contentContainerStyle={styles.iconList} renderRow={this.renderIcon} />
3、實現(xiàn)渲染函數(shù)renderIcon,默認(rèn)傳入四個參數(shù):
在renderIcon函數(shù)中定義每一個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> ) }
以上例子中的data是個一維數(shù)組,數(shù)組每個元素中包含title與image兩個字段,如果data是個二維數(shù)組,例如
其中data數(shù)組的一維元素中包含title與cars,而cars又是一個數(shù)組。使用ListView將其渲染為上面右圖所示按首字母分類的列表。
存儲原理:
ListView使用DataBlob來存儲二維數(shù)據(jù),其結(jié)構(gòu)如下:
DataBlob按照一定的格式組織二維數(shù)據(jù),如上左圖。DataBlob首先存儲數(shù)組的第一維section并為其分配ID,例如將上面的一維數(shù)組的"title":"A",存儲為DataBlob[0]="title":"A",分配sectionID為0,"title":"B",存儲為DataBlob[1]="title":"B",分配ID為1......以此類推。
之后再存儲數(shù)組的第二維row,例如"cars":[{"name":"奧迪","icon": "m_9_100.png"}],它的第一維sectionID為0,第二維rowID為2,將其存儲為DataBlob[0:2]={"name":"奧迪","icon": "m_9_100.png"}。
ListView使用步驟如下:
1、設(shè)置數(shù)據(jù)源
與一維ListView使用類似,首先在constructor中設(shè)置state為DataSource對象:
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對象時需要傳遞四個函數(shù)參數(shù)
2、在頁面中使用ListView
使用List View時設(shè)置其數(shù)據(jù)源及渲染方法
<ListView style={styles.carList} dataSource={this.state.carData} //定義數(shù)據(jù)源 renderRow={this.renderCarRow} //定義row的渲染方法 renderSectionHeader={this.renderCarSection} //定義SectionHeader渲染方法 />
3、實現(xiàn)渲染方法,方法默認(rèn)會傳入?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ù)加載到頁面
componentDidMount() { this.loadCarData(); } loadCarData(){ let dataBlob={}, //dataBlob對象 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ù)組的每個元素為一個數(shù)組 cars=carData[i].cars; //拿到每個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,需要傳入三個參數(shù) carData:this.state.carData.cloneWithRowsAndSections(dataBlob,sectionIDs,rowIDs) }) }
希望本文所述對大家React程序設(shè)計有所幫助。
當(dāng)前題目:ReactNative中ScrollView組件輪播圖與ListView渲染列表組件用法實例分析
文章路徑:http://jinyejixie.com/article32/pgsopc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)建站、企業(yè)建站、響應(yīng)式網(wǎng)站、定制網(wǎng)站、標(biāo)簽優(yōu)化、全網(wǎng)營銷推廣
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)