collapsible_tab_bar 0.0.2
collapsible_tab_bar: ^0.0.2 copied to clipboard
A Material tab bar that shrinks smoothly on scroll and snaps back, with pluggable tab styles: icon, text, or icon+label.
collapsible_tab_bar #
A Material tab bar that shrinks smoothly on scroll and snaps back on tap,
with pluggable tab styles. Drive the collapse from any scroll position (a
ScrollController/ScrollNotification, a SliverPersistentHeader, etc.) by
feeding a 0.0–1.0 progress value into CollapseScope.
Features #
ButtonsTabBar— aPreferredSizeWidgettab bar with per-tab filled or transparent card backgrounds, a selection underline, and a height that interpolates down to 31px as collapse progress goes from 0 to 1.- Four tab content styles:
ButtonsTab— image icon + label (shrinks/fades icon as it collapses).TextButtonsTab— text only, with optional badge overlay.IconButtonsTab—IconDataicon only.IconLabelTab—IconDataicon + label (same collapse behavior asButtonsTab, no image assets required).
CollapseScope— anInheritedWidgetthat publishescollapseProgress(0.0–1.0) andisCollapsedto the tab bar and its tabs.
Usage #
Drive CollapseScope's progress from your own scroll listener, then pass it
down to a ButtonsTabBar:
import 'package:collapsible_tab_bar/collapsible_tab_bar.dart';
class MyScreen extends StatefulWidget {
const MyScreen({super.key});
@override
State<MyScreen> createState() => _MyScreenState();
}
class _MyScreenState extends State<MyScreen> with TickerProviderStateMixin {
late final TabController _tabController =
TabController(length: 2, vsync: this);
late final AnimationController _collapseController = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 200),
);
bool _onScroll(ScrollNotification notification) {
if (notification.metrics.axis != Axis.vertical) return false;
if (notification is ScrollUpdateNotification) {
final double progress =
(notification.metrics.pixels / 60.0).clamp(0.0, 1.0);
_collapseController.value = progress;
}
return false;
}
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _collapseController,
builder: (context, _) {
return CollapseScope(
isCollapsed: _collapseController.value >= 1.0,
collapseProgress: _collapseController.value,
child: Scaffold(
appBar: ButtonsTabBar(
controller: _tabController,
tabs: const [
IconLabelTab(icon: Icons.home_rounded, label: 'Home', index: 0),
IconLabelTab(icon: Icons.person_rounded, label: 'Profile', index: 1),
],
),
body: NotificationListener<ScrollNotification>(
onNotification: _onScroll,
child: TabBarView(
controller: _tabController,
children: const [Center(child: Text('Home')), Center(child: Text('Profile'))],
),
),
),
);
},
);
}
}
See example/ for a complete, runnable demo (4-tab card-style bar matching
a real app's collapsing header, with corner radius animating from fully
rounded to top-only rounded as it collapses).
Notes #
ButtonsTab(the image-asset variant) readsSizeConfig.widthMultiplier/heightMultiplier, which this package exports. If you useButtonsTab, initialize sizing first (e.g. viaflutter_screenutil'sScreenUtilInitand callingSizeConfig.init()in itsbuilder) before the icon is built.TextButtonsTab,IconButtonsTab, andIconLabelTabdo not require this.