From e07fe0cc6063d48a5c0fc2245f54b58dd4f48c49 Mon Sep 17 00:00:00 2001 From: Petr Glotov Date: Tue, 15 Mar 2016 12:13:34 -0700 Subject: [PATCH] render empty section headers Summary:Changed behavior so that empty section headers are rendered, fixes this [issue](https://github.com/facebook/react-native/issues/5639). Closes https://github.com/facebook/react-native/pull/5713 Differential Revision: D3053765 Pulled By: sahrens fb-gh-sync-id: 59a78a4b19288b2acc04a7b166de8c2ad16eacd7 shipit-source-id: 59a78a4b19288b2acc04a7b166de8c2ad16eacd7 --- .../CustomComponents/ListView/ListView.js | 30 +++++++++++++++---- .../ListView/ListViewDataSource.js | 9 ++++++ 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/Libraries/CustomComponents/ListView/ListView.js b/Libraries/CustomComponents/ListView/ListView.js index eb642d73f..ae18efd69 100644 --- a/Libraries/CustomComponents/ListView/ListView.js +++ b/Libraries/CustomComponents/ListView/ListView.js @@ -215,6 +215,12 @@ var ListView = React.createClass({ * @platform ios */ stickyHeaderIndices: PropTypes.arrayOf(PropTypes.number), + /** + * Flag indicating whether empty section headers should be rendered. In the future release + * empty section headers will be rendered by default, and the flag will be deprecated. + * If empty sections are not desired to be rendered their indices should be excluded from sectionID object. + */ + enableEmptySections: PropTypes.bool, }, /** @@ -223,7 +229,7 @@ var ListView = React.createClass({ getMetrics: function() { return { contentLength: this.scrollProperties.contentLength, - totalRows: this.props.dataSource.getRowCount(), + totalRows: (this.props.enableEmptySections ? this.props.dataSource.getRowAndSectionCount() : this.props.dataSource.getRowCount()), renderedRows: this.state.curRenderedRowsCount, visibleRows: Object.keys(this._visibleRows).length, }; @@ -309,7 +315,7 @@ var ListView = React.createClass({ state.curRenderedRowsCount, props.initialListSize ), - props.dataSource.getRowCount() + props.enableEmptySections ? props.dataSource.getRowAndSectionCount() : props.dataSource.getRowCount() ), }; }, () => this._renderMoreRowsIfNeeded()); @@ -342,7 +348,19 @@ var ListView = React.createClass({ var sectionID = dataSource.sectionIdentities[sectionIdx]; var rowIDs = allRowIDs[sectionIdx]; if (rowIDs.length === 0) { - continue; + if (this.props.enableEmptySections === undefined) { + var warning = require('fbjs/lib/warning'); + warning(false, 'In next release empty section headers will be rendered.' + + ' In this release you can use \'enableEmptySections\' flag to render empty section headers.'); + continue; + } else { + var invariant = require('fbjs/lib/invariant'); + invariant( + this.props.enableEmptySections, + 'In next release \'enableEmptySections\' flag will be deprecated, empty section headers will always be rendered.' + + ' If empty section headers are not desirable their indices should be excluded from sectionIDs object.' + + ' In this release \'enableEmptySections\' may only have value \'true\' to allow empty section headers rendering.'); + } } if (this.props.renderSectionHeader) { @@ -483,7 +501,7 @@ var ListView = React.createClass({ if (this.props.onEndReached && this.scrollProperties.contentLength !== this._sentEndForContentLength && this._getDistanceFromEnd(this.scrollProperties) < this.props.onEndReachedThreshold && - this.state.curRenderedRowsCount === this.props.dataSource.getRowCount()) { + this.state.curRenderedRowsCount === (this.props.enableEmptySections ? this.props.dataSource.getRowAndSectionCount() : this.props.dataSource.getRowCount())) { this._sentEndForContentLength = this.scrollProperties.contentLength; this.props.onEndReached(event); return true; @@ -494,7 +512,7 @@ var ListView = React.createClass({ _renderMoreRowsIfNeeded: function() { if (this.scrollProperties.contentLength === null || this.scrollProperties.visibleLength === null || - this.state.curRenderedRowsCount === this.props.dataSource.getRowCount()) { + this.state.curRenderedRowsCount === (this.props.enableEmptySections ? this.props.dataSource.getRowAndSectionCount() : this.props.dataSource.getRowCount())) { this._maybeCallOnEndReached(); return; } @@ -509,7 +527,7 @@ var ListView = React.createClass({ this.setState((state, props) => { var rowsToRender = Math.min( state.curRenderedRowsCount + props.pageSize, - props.dataSource.getRowCount() + props.dataSource.getRowAndSectionCount() ); this._prevRenderedRowsCount = state.curRenderedRowsCount; return { diff --git a/Libraries/CustomComponents/ListView/ListViewDataSource.js b/Libraries/CustomComponents/ListView/ListViewDataSource.js index 1d14e50f5..0f65b1cce 100644 --- a/Libraries/CustomComponents/ListView/ListViewDataSource.js +++ b/Libraries/CustomComponents/ListView/ListViewDataSource.js @@ -186,6 +186,11 @@ class ListViewDataSource { typeof this._sectionHeaderHasChanged === 'function', 'Must provide a sectionHeaderHasChanged function with section data.' ); + invariant( + !sectionIdentities || !rowIdentities || sectionIdentities.length === rowIdentities.length, + 'row and section ids lengths must be the same' + ); + var newSource = new ListViewDataSource({ getRowData: this._getRowData, getSectionHeaderData: this._getSectionHeaderData, @@ -221,6 +226,10 @@ class ListViewDataSource { return this._cachedRowCount; } + getRowAndSectionCount(): number { + return (this._cachedRowCount + this.sectionIdentities.length); + } + /** * Returns if the row is dirtied and needs to be rerendered */