sliver_tabbar_with_mixed_list 1.0.1
sliver_tabbar_with_mixed_list: ^1.0.1 copied to clipboard
A sliver with a pinned button tab bar over sections that may nest and mix row heights. The tab bar follows the scroll position.
SliverTabBarWithMixedList #
A sliver with a pinned pill tab bar over a list of sections. Sections may nest, rows may have different heights, and the tab bar follows the scroll position — tapping a tab scrolls to its section.
Installation #
dependencies:
sliver_tabbar_with_mixed_list: ^1.0.0
Requires Dart 3.8 / Flutter 3.32 or newer.
Usage #
Describe the rows by extending HeaderItem, SubheaderItem, ChildItem and
VariantChildItem. Every row carries its own itemHeight; section offsets are
computed from those, so there is no offset arithmetic to get right.
class Course extends HeaderItem {
const Course({
required super.key,
required this.name,
required super.tabLabel,
super.children,
super.subSections,
}) : super(itemHeight: 64);
final String name;
}
class Dish extends ChildItem {
const Dish({required super.key, required this.name}) : super(itemHeight: 72);
final String name;
}
CustomScrollView(
controller: _controller,
slivers: <Widget>[
const SliverAppBar(pinned: true, title: Text('Menu')),
SliverTabBarWithMixedList(
controller: _controller,
listItemHeight: 72,
sections: sections,
headerBuilder: (context, item) => Text((item as Course).name),
childBuilder: (context, item) => Text((item as Dish).name),
onSectionChanged: (index) => setState(() => _section = index),
),
],
)
The controller must be the one the enclosing CustomScrollView uses.
Nested sections and mixed heights #
HeaderItem.subSections nests sections; a VariantChildItem is drawn by
variantChildBuilder and may be taller than the ordinary rows. Only top level
sections get a tab.
Custom tabs #
tabLabel names the default tab. generateTabs replaces them entirely:
generateTabs: (List<HeaderItem> sections) => <TabItem>[
for (int i = 0; i < sections.length; i++)
TabItem(key: ValueKey<int>(i), headerItem: sections[i], text: 'Tab $i'),
],
Parameters #
| Parameter | Default | Description |
|---|---|---|
sections |
required | Top level sections. |
listItemHeight |
required | Fallback row height when an item reports none. |
controller |
required | The enclosing scroll view's controller. |
childBuilder |
required | Builds an ordinary row. |
headerBuilder, subHeaderBuilder, variantChildBuilder |
null | Builders for the other row kinds. |
generateTabs |
null | Builds the tabs; defaults to one per section from tabLabel. |
onSectionChanged |
null | Called with the section index on every change. |
scrollAnimated / scrollDuration |
true / 300 ms |
Tab tap scrolling. |
startOffset |
0 |
Extent of the slivers above this one. |
customFooterWidget / footerHeight |
null | Space under a short last section. |
isTabBarVisible |
true |
Hides the tab bar entirely. |
tabBarButtonBackgroundColor, tabBarButtonUnselectedBackgroundColor, tabBarButtonRadius |
theme / 24 | The pill look. |
labelStyle, unselectedLabelStyle |
theme | Tab label styles. |
tabBarIndicator |
null | Takes over the selected look from the pill. |
prefixWidget, sufixWidget |
null | Widgets beside the tab bar. |
tabBarPadding, buttonMargin, contentPadding |
zero / 4 / zero | Spacing. |
itemExtentBuilder |
null | Overrides the row extent; must agree with itemHeight. |
Migrating from 0.0.9 #
- Offsets are computed for you.
offsetStart,childrenCountandchildrenHeightonHeaderItemare deprecated and ignored — delete the arithmetic. Getting it right by hand across nested, mixed-height sections was impractical; the package's own example had it wrong, so tapping a tab landed on the wrong section. childreanis nowchildren. The old name still works and is deprecated.generateTabs, the tab colours and the label styles are optional now, defaulting to the ambientColorScheme.- The
buttons_tabbardependency is gone, replaced by the framework'sTabBar. That package left a pending timer behind and threw a_TypeErrorwhen it was removed from the widget tree, which took the screen down on navigation. Section,SubSection,HeaderItem.paramsanditerateSectionswere unused scaffolding and have been removed.
License #
MIT.