您的当前位置:首页正文

React Native之ListView实现九宫格效果的示例

2020-11-27 来源:易榕旅网

概述

在安卓原生开发中,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确认网格数量

<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,设置每一个网格的宽度样式

itemLayout:{ 
 flex:1, 
 width:Util.size.width/3, 
 height:Util.size.width/3, 
 alignItems:'center', 
 justifyContent:'center', 
 borderWidth: Util.pixel, 
 borderColor: '#eaeaea' 
 }, 

3,设置contentContainerStyle相应属性

grid: { 
 justifyContent: 'space-around', 
 flexDirection: 'row', 
 flexWrap: 'wrap' 
 }, 

这里需要说明下,由于ListView的默认方向是纵向的,所以需要设置ListView的contentContainerStyle属性,添加flexDirection:‘row'。其次,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); 

效果如图(数据源自己加)

显示全文