目标:简化及规范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的封装相关推荐

  1. React Native加载动画,lottie-web 将json解析成动画

    1.安装依赖 npm install lottie-web --save 2.建立resources文件夹,内部导入AE动画的json文件且新建Lottie.js文件,封装Component组件 Lo ...

  2. android: 动态加载碎片布局的技巧

    虽然动态添加碎片的功能很强大,可以解决很多实际开发中的问题,但是它毕竟只是在 一个布局文件中进行一些添加和替换操作.如果程序能够根据设备的分辨率或屏幕大小在运 行时来决定加载哪个布局,那我们可发挥的空 ...

  3. React 16 加载性能优化指南

    关于 React 应用加载的优化,其实网上类似的文章已经有太多太多了,随便一搜就是一堆,已经成为了一个老生常谈的问题. 但随着 React 16 和 Webpack 4.0 的发布,很多过去的优化手段 ...

  4. Android RecyclerView加载复杂布局

    Android RecyclerView加载复杂布局 用一个RecyclerView实现多种复杂布局,复用机制要保存 简书:Android RecyclerView加载复杂布局 demo源码挂载在码云 ...

  5. React.js加载组件以及JSX脚本处理代码

    React.js是一个组件化的JS界面开发库,可以结合XML格式的脚本语法JSX. 如果你的页面中包含了这样的代码,需要将JSX代码预编译为Raw JavaScript,不然会提示有语法错误" ...

  6. 【05】Android时时监测手机的旋转角度 根据旋转角度确定在什么角度加载竖屏布局 在什么时候加载横屏布局

    一.场景描述: 近期开发中遇到个问题,就是我们在做横竖屏切换的功能时,横竖屏布局是操作系统去感知的,作为开发员没法确定Activity在什么时候加载横屏布局,在什么时候加载竖屏布局.因此为了找到加载横 ...

  7. RecyclerView显示加载多种布局的原理

    RecyclerView是对ListView的封装,所以ListView上能用的方法对RecyclerView同样适用,并且会更简单 在实际开发中,我们可能需要一个列表,显示多种布局,getItemV ...

  8. 在React中加载数据:redux-thunk,redux-saga,suspense,hooks

    目录 介绍 初始设置 模拟服务器 项目和API调用 Redux-thunk Redux-saga Suspense Hooks 结论 介绍 React是一个用于构建用户界面的JavaScript库.经 ...

  9. React 异步加载组件

    1,通过 import() 语法动态引入组件. 2,React.lazy 接受一个函数,这个函数需要动态调用 import(). 3,然后应在 Suspense 组件中渲染 lazy 组件,fallb ...

最新文章

  1. 神经网络早期的感知机模型
  2. 1920+1080+android三星手机,三星Galaxy Note3能拍摄1080p视频吗?支持1080p播放吗?
  3. 基于嵌入式webserver的服务器状态监控
  4. 详解NLP技术中的:预训练模型、图神经网络、模型压缩、知识图谱
  5. python监控linux运行程序_如何在linux/tcl/python中监控正在打开或启动的应用程序?...
  6. python学习笔记(十一)-python程序目录工程化
  7. bzoj1076 奖励关(概率dp)(状态压缩)
  8. 常用游戏测试用例模板
  9. 回顾线性系统和非线性系统
  10. 手机 android.downloader病毒,Android手机出现史上最强木马 感染后无法删除
  11. 不要让采购欺诈吃掉你的利润
  12. Python入门_打印矩形
  13. arcsin在matlab中怎么输,matlab arcsin
  14. dede标签调用大全
  15. minigui相关硬件加速添加方法
  16. VMWare下载安装以及创建虚拟机教程
  17. 应用上云2小时烧掉近50万,创始人:差点破产
  18. 《软件方法(上)业务建模和需求》第2版 勘误(2021年10月9日更新)
  19. 单片机之动态数码管篇
  20. 1037: 四则运算 C语言

热门文章

  1. 使用Subversion进行版本控制 附录A
  2. ElasticSearch5.5.1插件分类
  3. freemarker list size问题
  4. Leetcode PHP题解--D6 595. Big Countries
  5. katalon中REST URL占位参数动态化
  6. Linux-文件查找
  7. 快速开发基于 HTML5 网络拓扑图应用之 DataBinding 数据绑定篇
  8. Cython进阶--用Cython封装Callback函数
  9. http消息当中,post和get两种请求方式的区别
  10. struts2的action从request获取参数值的几种方式