概述
在安卓原生開(kāi)發(fā)中,ListView是很常用的一個(gè)列表控件,那么React Native(RN)如何實(shí)現(xiàn)該功能呢?我們來(lái)看一下ListView的源碼
ListView是基于ScrollView擴(kuò)展得來(lái)的,所以具有ScrollView的相關(guān)屬性:
dataSource:數(shù)據(jù)源,類似于安卓中我們傳入BaseAdapter的數(shù)據(jù)集合。
renderRow:渲染某一行,類似于BaseAdapter中的getItem方法。
onEndReached:簡(jiǎn)單說(shuō)就是用于分頁(yè)操作,在安卓中原生開(kāi)發(fā)中,我們需要自己實(shí)現(xiàn)相應(yīng)的方法。
onEndReachedThreshold:調(diào)用onEndReached之前的臨界值,單位是像素。
refreshControl:指定RefreshControl組件,用于為ScrollView提供下拉刷新功能。(該屬性是繼承與ScrollView)
renderHeader:渲染頭部View,類似于安卓ListView中的addHeader.
以上的屬性基本可以解決一些常見(jiàn)的列表需求,如果我們想要實(shí)現(xiàn)網(wǎng)格的效果,也可以借助該組件來(lái)實(shí)現(xiàn),有點(diǎn)類似于安卓中的RecyclerView控件。
pageSize:渲染的網(wǎng)格數(shù),類似于安卓GridView中的numColumns.
contentContainerStyle:該屬性是繼承于ScrollView,主要作用于該組件的內(nèi)容容器上。
要用ListView實(shí)現(xiàn)九宮格的效果:
1,配置pageSize確認(rèn)網(wǎng)格數(shù)量
<ListView automaticallyAdjustContentInsets={false} contentContainerStyle={styles.grid} dataSource={this.state.dataSource} renderRow={this.renderRow.bind(this)} pageSize={3} refreshControl={ <RefreshControl onRefresh={this.onRefresh.bind(this)} refreshing={this.state.isLoading} colors={['#ff0000', '#00ff00', '#0000ff']} enabled={true} /> } />
2,設(shè)置每一個(gè)網(wǎng)格的寬度樣式
itemLayout:{ flex:1, width:Util.size.width/3, height:Util.size.width/3, alignItems:'center', justifyContent:'center', borderWidth: Util.pixel, borderColor: '#eaeaea' },
3,設(shè)置contentContainerStyle相應(yīng)屬性
grid: { justifyContent: 'space-around', flexDirection: 'row', flexWrap: 'wrap' },
這里需要說(shuō)明下,由于ListView的默認(rèn)方向是縱向的,所以需要設(shè)置ListView的contentContainerStyle屬性,添加flexDirection:‘row'。其次,ListView在同一行顯示,而且通過(guò)flexWrap:'wrap'設(shè)置自動(dòng)換行。
注:flexWrap屬性:wrap、nowrap,wrap:空間不足的情況下自動(dòng)換行,nowrap:空間不足,壓縮容器,不會(huì)自動(dòng)換行。
以下是完整代碼:
import React, { Component } from 'react'; import { AppRegistry, StyleSheet, Text, View, ListView, Image, TouchableOpacity, // 不透明觸摸 AlertIOS } from 'react-native'; // 獲取屏幕寬度 var Dimensions = require('Dimensions'); const screenW = Dimensions.get('window').width; // 導(dǎo)入json數(shù)據(jù) var shareData = require('./shareData.json'); // 一些常亮設(shè)置 const cols = 3; const cellWH = 100; const vMargin = (screenW - cellWH * cols) / (cols + 1); const hMargin = 25; // ES5 var ListViewDemo = React.createClass({ // 初始化狀態(tài)值(可以變化) getInitialState(){ // 創(chuàng)建數(shù)據(jù)源 var ds = new ListView.DataSource({rowHasChanged:(r1,r2) => r1 !== r2}); return{ dataSource:ds.cloneWithRows(shareData.data) } }, render(){ return( <ListView dataSource={this.state.dataSource} renderRow={this.renderRow} contentContainerStyle={styles.listViewStyle} /> ); }, // 返回cell renderRow(rowData){ return( <TouchableOpacity activeOpacity={0.8} onPress={()=>{AlertIOS.alert('點(diǎn)擊了')}} > <View style={styles.innerViewStyle}> <Image source={{uri:rowData.icon}} style={styles.iconStyle} /> <Text>{rowData.title}</Text> </View> </TouchableOpacity> ); }, }); const styles = StyleSheet.create({ listViewStyle:{ // 主軸方向 flexDirection:'row', // 一行顯示不下,換一行 flexWrap:'wrap', // 側(cè)軸方向 alignItems:'center', // 必須設(shè)置,否則換行不起作用 }, innerViewStyle:{ width:cellWH, height:cellWH, marginLeft:vMargin, marginTop:hMargin, // 文字內(nèi)容居中對(duì)齊 alignItems:'center' }, iconStyle:{ width:80, height:80, }, }); AppRegistry.registerComponent('ListViewDemo', () => ListViewDemo);
效果如圖(數(shù)據(jù)源自己加)
聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com