From ab3f70fb4062f6cc4f728ea11df2f239946a3c9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Beffa?= Date: Thu, 4 Jul 2024 17:03:54 +0200 Subject: [PATCH] Add header support --- lib/grouped_list.dart | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/lib/grouped_list.dart b/lib/grouped_list.dart index 182947a..18abed4 100644 --- a/lib/grouped_list.dart +++ b/lib/grouped_list.dart @@ -210,6 +210,9 @@ class GroupedListView extends StatefulWidget { /// the scroll position changes drastically. final double? itemExtent; + /// Widget to be placed at the top of the list. + final Widget? header; + /// Widget to be placed at the bottom of the list. final Widget? footer; @@ -258,6 +261,7 @@ class GroupedListView extends StatefulWidget { this.restorationId, this.semanticChildCount, this.itemExtent, + this.header, this.footer, }) : assert(itemBuilder != null || indexedItemBuilder != null || @@ -326,11 +330,15 @@ class _GroupedListViewState extends State> { /// If the [index] points to an separator and the previous and next items /// are in different groups, a group header widget is displayed. Widget itemBuilder(context, index) { - if (widget.footer != null && index == _sortedElements.length * 2) { + if (widget.header != null && index == 0) { + return widget.header!; + } + if (widget.footer != null && index == _itemCount() - 1) { return widget.footer!; } - var actualIndex = index ~/ 2; - if (index == hiddenIndex) { + var indexWithoutHeader = index - (widget.header != null ? 1 : 0); + var actualIndex = indexWithoutHeader ~/ 2; + if (indexWithoutHeader == hiddenIndex) { return Opacity( opacity: widget.useStickyGroupSeparators ? 0 : 1, child: _buildGroupSeparator(_sortedElements[actualIndex]), @@ -345,7 +353,7 @@ class _GroupedListViewState extends State> { var next = isValidIndex(nextIndex) ? widget.groupBy(_sortedElements[nextIndex]) : null; - if (isSeparator(index)) { + if (isSeparator(indexWithoutHeader)) { if (prev != curr) { return _buildGroupSeparator(_sortedElements[actualIndex]); } @@ -372,9 +380,7 @@ class _GroupedListViewState extends State> { restorationId: widget.restorationId, keyboardDismissBehavior: widget.keyboardDismissBehavior, semanticChildCount: widget.semanticChildCount, - itemCount: widget.footer == null - ? _sortedElements.length * 2 - : (_sortedElements.length * 2) + 1, + itemCount: _itemCount(), addAutomaticKeepAlives: widget.addAutomaticKeepAlives, addRepaintBoundaries: widget.addRepaintBoundaries, addSemanticIndexes: widget.addSemanticIndexes, @@ -394,6 +400,10 @@ class _GroupedListViewState extends State> { ); } + int _itemCount() { + return _sortedElements.length * 2 + (widget.footer == null ? 0 : 1) + (widget.header == null ? 0 : 1); + } + /// Returns the widget for element positioned at [index]. The widget is /// retrieved either by [widget.indexedItemBuilder], [widget.itemBuilder] /// or [widget.interdependentItemBuilder].