React Native之ListView实现九宫格效果

时间:2022-04-26
本文章向大家介绍React Native之ListView实现九宫格效果,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

概述

在安卓原生开发中,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);

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