React Native 加载多类型布局的实现——分类列表SectionList的封装
目标:简化及规范SectionList的使用。
实现:基于SectionList的封装。
适用的情况
普通的线布局+列表/分类列表+普通线程布局+列表/分类列表。如下图:
如上图中1、2、3、4(评论回复模块)就是普通的线布+列表+普通线程布局+分类列表的形式。
封装后的BaseSectionList.js类,如下:
/*** @desc* @author MaRui*/
import {View,StyleSheet,SectionList
} from 'react-native';
import React, {Component} from "react";
// [
// {data: [], layoutType: 0, title: {}}
// ]
export default class BaseSectionList extends Component {constructor(props) {super(props);this.state = {dataList: []};}componentDidMount() {if (!this.props.data) {return}let newDataList = [];if (this.props.data && React.Children.toArray(this.props.children).length !== this.props.length) {this.setState({dataList: []});return;}for (let i = 0; i < this.props.data.length; i++) {if (this.props.data[i].length === 0) {newDataList.splice(newDataList.length, 0, {title: {}, data: [], layoutType: i});continue}for (let j = 0; j < this.props.data[i].length; j++) {let datumElement = this.props.data[i][j];if (datumElement) {let title = this.props.data[j].title;let data = this.props.data[j].content;newDataList.splice(newDataList.length, 0, {title: title, data: data, layoutType: i});} else {newDataList.splice(newDataList.length, 0, {title: {}, data: [], layoutType: i});}}}this.setState({dataList: newDataList});}componentWillReceiveProps(nextProps) {if (!this.props.data) {return}let isRefresh = false;if (this.props.data !== nextProps.data && this.props.data.length !== nextProps.data.length) {isRefresh = true;} else {for (let i = 0; i < this.props.data.length; i++) {if (this.props.data[i] !== nextProps.data[i]) {isRefresh = true;break;}}}if (isRefresh) {let newDataList = [];for (let i = 0; i < nextProps.data.length; i++) {if (nextProps.data[i].length === 1 && nextProps.data[i][0].baseSectionListType === 'baseSectionListContent') {newDataList.splice(newDataList.length, 0, {title: {}, data: [], layoutType: i});continue}for (let j = 0; j < nextProps.data[i].length; j++) {let datumElement = nextProps.data[i][j];if (datumElement) {let title = datumElement.title;let data = datumElement.content;newDataList.splice(newDataList.length, 0, {title: title, data: data, layoutType: i});} else {newDataList.splice(newDataList.length, 0, {title: {}, data: [], layoutType: i});}}}this.setState({dataList: newDataList}, () => {// alert('值:'+JSON.stringify(this.state.dataList)+'\n个数:'+this.state.dataList.length);});}}//分组创建的cellcellView = (data) => {if (data && this.props.children) {if (React.Children.toArray(this.props.children)[data.section.layoutType].props.renderCell) {return React.Children.toArray(this.props.children)[data.section.layoutType].props.renderCell(data)}// 建议数据少时使用if (React.Children.toArray(this.props.children)[data.section.layoutType].props.renderCellIsShow && !this.props.itemIsShow) {return React.Children.toArray(this.props.children)[data.section.layoutType].props.renderCellIsShow(data)}}return <View/>};//列表分组的headerheaderView = (data) => {if (data && this.props.children) {if (React.Children.toArray(this.props.children)[data.section.layoutType].props.renderHeader) {return React.Children.toArray(this.props.children)[data.section.layoutType].props.renderHeader(data)}// 建议数据少时使用if (React.Children.toArray(this.props.children)[data.section.layoutType].props.renderHeaderIsShow && !this.props.itemIsShow) {return React.Children.toArray(this.props.children)[data.section.layoutType].props.renderHeaderIsShow(data)}}return <View/>};extraUniqueKey = (item, index) => {return index + item;};render() {return (<View style={[{flex: 1}]}><View style={styles.container}><SectionList{...this.props}sections={this.state.dataList}renderItem={this.cellView}keyExtractor={this.extraUniqueKey}renderSectionHeader={this.headerView}scrollEnabled={true}stickySectionHeadersEnabled={false}/></View></View>);}
}const styles = StyleSheet.create({container: {flex: 1},});
主要实现了,不用给每一块的数据做标记就可以实现分类列表的显示、多类型布局的简便实现。之后补充封装代码的解析
BaseSectionList的使用,实现上图如下:
布局:
<BaseSectionList// 此处可以添加设置SectionList的任何属性,比如头部布局、底部布局、分割线等等style={{flex: 1}}data={this.props.data}ListHeaderComponent={this.headerRender}><ViewrenderCell={this.renderListCell}/><ViewrenderHeader={this.renderTitle}/><ViewrenderHeader={this.renderComment}renderCell={this.renderReply}/></BaseSectionList>
其中布局1为普通布局可以设置为ListHeaderComponent。此后,每一块布局都添加一个子view,234三块布局就添加三个标签“<View/>”。具体设置:比如布局2是列表则添加一个子view只设置renderCell,renderCell是list的item的布局。布局3是一个线性布局,可设置renderHeader即可。布局4是一个二级列表即分类列表,需要同时设置renderHeader和renderCell分别代表分类标题布局和分类列表item的布局。
数据结构:
let data = [];
data.splice(0, 0, [{title: {}, content: []}]);
data.splice(1, 0, [{baseSectionListType: 'baseSectionListContent'}]);
data.splice(2, 0, [{title: {'课程'}, content: ['语文', '数学', '英语']},{title: {'班级'}, content: ['一班', '二班', '三班']},{title: {'老师'}, content: ['张老师', '王老师', '李老师']}]);
传输的数据是一个数组。上边添加的三个布局,则数组的长度必须是3。每个元素也必须是数组,该例子的格式即是 [ [ ], [ ], [ ] ]。下面说每个元素的填充。分以下三种情况:
- 模块是列表,比如:布局2
元素是一个数组,长度是1。[{title: {}, content: []}]。title设置为空对象,content传数组即该块列表对应的数组。 - 模块是线性布局,比如:模块3
元素是一个数组,长度是1, 元素是{baseSectionListType: ‘baseSectionListContent’}。这个是固定不变的,实际只起到占位符的作用。该模块的数据自己管理。 - 模块是分类列表,比如:模块4
元素是一个数组,数组的长度是分类列表的类的个数,比如有3类[{title: {}, content: []}, {title: {}, content: []}, {title: {}, content: []}]。title是标题对应的数据,content传数组即该块列表对应的数组。
React Native 加载多类型布局的实现——分类列表SectionList的封装相关推荐
- React Native加载动画,lottie-web 将json解析成动画
1.安装依赖 npm install lottie-web --save 2.建立resources文件夹,内部导入AE动画的json文件且新建Lottie.js文件,封装Component组件 Lo ...
- android: 动态加载碎片布局的技巧
虽然动态添加碎片的功能很强大,可以解决很多实际开发中的问题,但是它毕竟只是在 一个布局文件中进行一些添加和替换操作.如果程序能够根据设备的分辨率或屏幕大小在运 行时来决定加载哪个布局,那我们可发挥的空 ...
- React 16 加载性能优化指南
关于 React 应用加载的优化,其实网上类似的文章已经有太多太多了,随便一搜就是一堆,已经成为了一个老生常谈的问题. 但随着 React 16 和 Webpack 4.0 的发布,很多过去的优化手段 ...
- Android RecyclerView加载复杂布局
Android RecyclerView加载复杂布局 用一个RecyclerView实现多种复杂布局,复用机制要保存 简书:Android RecyclerView加载复杂布局 demo源码挂载在码云 ...
- React.js加载组件以及JSX脚本处理代码
React.js是一个组件化的JS界面开发库,可以结合XML格式的脚本语法JSX. 如果你的页面中包含了这样的代码,需要将JSX代码预编译为Raw JavaScript,不然会提示有语法错误" ...
- 【05】Android时时监测手机的旋转角度 根据旋转角度确定在什么角度加载竖屏布局 在什么时候加载横屏布局
一.场景描述: 近期开发中遇到个问题,就是我们在做横竖屏切换的功能时,横竖屏布局是操作系统去感知的,作为开发员没法确定Activity在什么时候加载横屏布局,在什么时候加载竖屏布局.因此为了找到加载横 ...
- RecyclerView显示加载多种布局的原理
RecyclerView是对ListView的封装,所以ListView上能用的方法对RecyclerView同样适用,并且会更简单 在实际开发中,我们可能需要一个列表,显示多种布局,getItemV ...
- 在React中加载数据:redux-thunk,redux-saga,suspense,hooks
目录 介绍 初始设置 模拟服务器 项目和API调用 Redux-thunk Redux-saga Suspense Hooks 结论 介绍 React是一个用于构建用户界面的JavaScript库.经 ...
- React 异步加载组件
1,通过 import() 语法动态引入组件. 2,React.lazy 接受一个函数,这个函数需要动态调用 import(). 3,然后应在 Suspense 组件中渲染 lazy 组件,fallb ...
最新文章
- 神经网络早期的感知机模型
- 1920+1080+android三星手机,三星Galaxy Note3能拍摄1080p视频吗?支持1080p播放吗?
- 基于嵌入式webserver的服务器状态监控
- 详解NLP技术中的:预训练模型、图神经网络、模型压缩、知识图谱
- python监控linux运行程序_如何在linux/tcl/python中监控正在打开或启动的应用程序?...
- python学习笔记(十一)-python程序目录工程化
- bzoj1076 奖励关(概率dp)(状态压缩)
- 常用游戏测试用例模板
- 回顾线性系统和非线性系统
- 手机 android.downloader病毒,Android手机出现史上最强木马 感染后无法删除
- 不要让采购欺诈吃掉你的利润
- Python入门_打印矩形
- arcsin在matlab中怎么输,matlab arcsin
- dede标签调用大全
- minigui相关硬件加速添加方法
- VMWare下载安装以及创建虚拟机教程
- 应用上云2小时烧掉近50万,创始人:差点破产
- 《软件方法(上)业务建模和需求》第2版 勘误(2021年10月9日更新)
- 单片机之动态数码管篇
- 1037: 四则运算 C语言