概述
在安卓原生开发中,ListView是很常用的一个列表控件,那么React Native(RN)如何实现该功能呢?我们来看一下ListView的源码
ListView是基于ScrollView扩展得来的,所以具有ScrollView的相关属性:
dataSource:数据源,类似于安卓中我们传入BaseAdapter的数据集合。
renderRow:渲染某一行,类似于BaseAdapter中的getItem方法。
onEndReached:简单说就是用于分页操作,在安卓中原生开发中,我们需要自己实现相应的方法。
onEndReachedThreshold:调用onEndReached之前的临界值,单位是像素。
refreshControl:指定RefreshControl组件,用于为ScrollView提供下拉刷新功能。(该属性是继承与ScrollView)
renderHeader:渲染头部View,类似于安卓ListView中的addHeader.
以上的属性基本可以解决一些常见的列表需求,如果我们想要实现网格的效果,也可以借助该组件来实现,有点类似于安卓中的RecyclerView控件。
pageSize:渲染的网格数,类似于安卓GridView中的numColumns.
contentContainerStyle:该属性是继承于ScrollView,主要作用于该组件的内容容器上。
要用ListView实现九宫格的效果:
1,配置pageSize确认网格数量
2,设置每一个网格的宽度样式
- <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}
- />
- }
- />
3,设置contentContainerStyle相应属性
- itemLayout:{
- flex:1,width:Util.size.width/3,height:Util.size.width/3,alignItems:'center',justifyContent:'center',borderWidth: Util.pixel,borderColor: '#eaeaea'
- },
这里需要说明下,由于ListView的默认方向是纵向的,所以需要设置ListView的contentContainerStyle属性,添加flexDirection:‘row’
- grid: {
- justifyContent: 'space-around',flexDirection: 'row',flexWrap: 'wrap'
- },
其次,ListView在同一行显示,而且通过flexWrap:’wrap’设置自动换行。
注:flexWrap属性:wrap、nowrap,wrap:空间不足的情况下自动换行,nowrap:空间不足,压缩容器,不会自动换行。
以下是完整代码:
- 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;
- // 导入json数据
- var shareData = require('./shareData.json');
- // 一些常亮设置
- const cols = 3;
- const cellWH = 100;
- const vMargin = (screenW - cellWH * cols) / (cols + 1);
- const hMargin = 25;
- // ES5
- var ListViewDemo = React.createClass({
- // 初始化状态值(可以变化)
- getInitialState(){
- // 创建数据源
- 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('点击了')}} >
- <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',// 侧轴方向
- alignItems:'center',// 必须设置,否则换行不起作用
- },innerViewStyle:{
- width:cellWH,height:cellWH,marginLeft:vMargin,marginTop:hMargin,// 文字内容居中对齐
- alignItems:'center'
- },iconStyle:{
- width:80,height:80,},});
- AppRegistry.registerComponent('ListViewDemo',() => ListViewDemo);
效果如图(数据源自己加)