React Native 加载多类型布局的实现——分类列表SectionList的封装
生活随笔
收集整理的這篇文章主要介紹了
React Native 加载多类型布局的实现——分类列表SectionList的封装
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
目標:簡化及規范SectionList的使用。
實現:基于SectionList的封裝。
適用的情況
??????普通的線布局+列表/分類列表+普通線程布局+列表/分類列表。如下圖:
封裝后的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的封装的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 抖音如何充值抖币
- 下一篇: 宝骏云朵官宣 8 月 10 日上市:先期