### Track Visible Lists with ExtendedVisibilityDetector Source: https://github.com/fluttercandies/extended_nested_scroll_view/blob/master/README.md This example illustrates the usage of `ExtendedVisibilityDetector` from the `extended_nested_scroll_view` package. It allows developers to identify which list within a tab view is currently visible by assigning a unique key to each detector. ```dart ExtendedVisibilityDetector( uniqueKey: const Key('Tab1'), child: ListView(), ) ``` -------------------------------- ### Flutter Dart Example: ExtendedNestedScrollView with TabBar Source: https://context7.com/fluttercandies/extended_nested_scroll_view/llms.txt Demonstrates setting up an ExtendedNestedScrollView that contains a TabBar in its header and a TabBarView in its body. It uses `onlyOneScrollInBody: true` to manage scroll synchronization and `PageStorageKey` to preserve scroll positions for each tab's content. ```dart import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart'; import 'package:flutter/material.dart'; class TabBarExample extends StatefulWidget { @override _TabBarExampleState createState() => _TabBarExampleState(); } class _TabBarExampleState extends State with TickerProviderStateMixin { late TabController tabController; @override void initState() { super.initState(); tabController = TabController(length: 3, vsync: this); } @override void dispose() { tabController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final double statusBarHeight = MediaQuery.of(context).padding.top; final double pinnedHeaderHeight = statusBarHeight + kToolbarHeight; return Scaffold( body: ExtendedNestedScrollView( // Prevent multiple scroll positions from scrolling together onlyOneScrollInBody: true, pinnedHeaderSliverHeightBuilder: () => pinnedHeaderHeight, headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) { return [ SliverAppBar( pinned: true, expandedHeight: 200.0, title: Text('Profile'), bottom: TabBar( controller: tabController, tabs: [ Tab(text: 'Posts'), Tab(text: 'Photos'), Tab(text: 'Videos'), ], ), ), ]; }, body: TabBarView( controller: tabController, children: [ // Use PageStorageKey to maintain scroll position ListView.builder( key: PageStorageKey('Posts'), physics: ClampingScrollPhysics(), itemCount: 50, itemBuilder: (context, index) { return ListTile(title: Text('Post $index')); }, ), ListView.builder( key: PageStorageKey('Photos'), physics: ClampingScrollPhysics(), itemCount: 50, itemBuilder: (context, index) { return Container( height: 200, color: Colors.grey[300], margin: EdgeInsets.all(8), child: Center(child: Text('Photo $index')), ); }, ), ListView.builder( key: PageStorageKey('Videos'), physics: ClampingScrollPhysics(), itemCount: 50, itemBuilder: (context, index) { return ListTile(title: Text('Video $index')); }, ), ], ), ), ); } } ``` -------------------------------- ### Implement Active Tab Detection with ExtendedVisibilityDetector in Flutter Source: https://context7.com/fluttercandies/extended_nested_scroll_view/llms.txt This Dart code demonstrates how to use ExtendedVisibilityDetector to identify the currently active and visible tab within a TabBarView. It requires the 'extended_nested_scroll_view' and 'flutter/material.dart' packages. The example sets up a Scaffold with an ExtendedNestedScrollView containing a TabBarView, where each tab's content is wrapped in an ExtendedVisibilityDetector. ```dart import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart'; import 'package:flutter/material.dart'; class VisibilityExample extends StatefulWidget { @override _VisibilityExampleState createState() => _VisibilityExampleState(); } class _VisibilityExampleState extends State with TickerProviderStateMixin { late TabController tabController; @override void initState() { super.initState(); tabController = TabController(length: 2, vsync: this); } @override Widget build(BuildContext context) { return Scaffold( body: ExtendedNestedScrollView( onlyOneScrollInBody: true, pinnedHeaderSliverHeightBuilder: () { return MediaQuery.of(context).padding.top + kToolbarHeight; }, headerSliverBuilder: (context, innerBoxIsScrolled) { return [ SliverAppBar( pinned: true, title: Text('Visibility Tracking'), bottom: TabBar( controller: tabController, tabs: [Tab(text: 'Tab 1'), Tab(text: 'Tab 2')], ), ), ]; }, body: TabBarView( controller: tabController, children: [ ExtendedVisibilityDetector( uniqueKey: Key('Tab1'), child: ListView.builder( key: PageStorageKey('Tab1'), itemCount: 100, itemBuilder: (context, index) { return ListTile(title: Text('Tab 1 - Item $index')); }, ), ), ExtendedVisibilityDetector( uniqueKey: Key('Tab2'), child: ListView.builder( key: PageStorageKey('Tab2'), itemCount: 100, itemBuilder: (context, index) { return ListTile(title: Text('Tab 2 - Item $index')); }, ), ), ], ), ), ); } @override void dispose() { tabController.dispose(); super.dispose(); } } ``` -------------------------------- ### Control Scrolling with GlobalKey in ExtendedNestedScrollView Source: https://context7.com/fluttercandies/extended_nested_scroll_view/llms.txt Shows how to use a GlobalKey to access the scroll controllers of an ExtendedNestedScrollView for programmatic scrolling. This allows actions like scrolling to the top of the content. ```dart import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart'; import 'package:flutter/material.dart'; class ScrollControlExample extends StatefulWidget { @override _ScrollControlExampleState createState() => _ScrollControlExampleState(); } class _ScrollControlExampleState extends State { final GlobalKey nestedScrollKey = GlobalKey(); void scrollToTop() { // Access outer controller to scroll to top nestedScrollKey.currentState?.outerController.animateTo( 0.0, duration: Duration(milliseconds: 500), curve: Curves.easeOut, ); } @override Widget build(BuildContext context) { return Scaffold( body: ExtendedNestedScrollView( key: nestedScrollKey, pinnedHeaderSliverHeightBuilder: () { return MediaQuery.of(context).padding.top + kToolbarHeight; }, headerSliverBuilder: (context, innerBoxIsScrolled) { return [ SliverAppBar( pinned: true, expandedHeight: 200.0, title: Text('Scroll Control'), ), ]; }, body: ListView.builder( itemCount: 100, itemBuilder: (context, index) { return ListTile( title: Text('Item $index'), ); }, ), ), floatingActionButton: FloatingActionButton( onPressed: scrollToTop, child: Icon(Icons.arrow_upward), tooltip: 'Scroll to top', ), ); } } ``` -------------------------------- ### Implement Floating Headers with ExtendedNestedScrollView Source: https://context7.com/fluttercandies/extended_nested_scroll_view/llms.txt Demonstrates how to enable floating header slivers in ExtendedNestedScrollView for responsive app bar behavior. This allows the header to float and reappear as the user scrolls. ```dart import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart'; import 'package:flutter/material.dart'; class FloatingHeaderExample extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( body: ExtendedNestedScrollView( // Enable floating behavior for header slivers floatHeaderSlivers: true, scrollDirection: Axis.vertical, reverse: false, physics: BouncingScrollPhysics(), pinnedHeaderSliverHeightBuilder: () { return MediaQuery.of(context).padding.top + kToolbarHeight; }, headerSliverBuilder: (context, innerBoxIsScrolled) { return [ SliverAppBar( floating: true, snap: true, pinned: false, expandedHeight: 200.0, title: Text('Floating Header'), forceElevated: innerBoxIsScrolled, flexibleSpace: FlexibleSpaceBar( background: Image.network( 'https://example.com/header.jpg', fit: BoxFit.cover, ), ), ), ]; }, body: ListView.builder( physics: ClampingScrollPhysics(), itemCount: 100, itemBuilder: (context, index) { return Card( margin: EdgeInsets.all(8), child: ListTile( leading: CircleAvatar(child: Text('$index')), title: Text('Item $index'), subtitle: Text('Subtitle for item $index'), trailing: Icon(Icons.arrow_forward_ios), ), ); }, ), ), ); } } ``` -------------------------------- ### ExtendedNestedScrollView with Pinned Header in Dart Source: https://context7.com/fluttercandies/extended_nested_scroll_view/llms.txt Demonstrates basic usage of ExtendedNestedScrollView to configure a pinned header height, preventing overlap issues with content. Requires the 'extended_nested_scroll_view' package. ```dart import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart'; import 'package:flutter/material.dart'; class BasicExample extends StatelessWidget { @override Widget build(BuildContext context) { final double statusBarHeight = MediaQuery.of(context).padding.top; final double pinnedHeaderHeight = statusBarHeight + kToolbarHeight; return ExtendedNestedScrollView( // Fix pinned header overlap issue pinnedHeaderSliverHeightBuilder: () { return pinnedHeaderHeight; }, headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) { return [ SliverAppBar( pinned: true, expandedHeight: 200.0, title: Text('Extended Nested Scroll'), flexibleSpace: FlexibleSpaceBar( background: Image.network( 'https://example.com/header.jpg', fit: BoxFit.cover, ), ), ), ]; }, body: ListView.builder( itemCount: 100, itemBuilder: (context, index) { return ListTile( title: Text('Item $index'), ); }, ), ); } } ``` -------------------------------- ### Set Pinned Sliver Header Height in ExtendedNestedScrollView Source: https://github.com/fluttercandies/extended_nested_scroll_view/blob/master/README.md This snippet demonstrates how to define the total height of pinned sliver headers by implementing the `pinnedHeaderSliverHeightBuilder` callback in `ExtendedNestedScrollView`. It calculates the height based on the status bar, toolbar, and tab bar heights. ```dart var tabBarHeight = primaryTabBar.preferredSize.height; var pinnedHeaderHeight = //statusBar height statusBarHeight + //pinned SliverAppBar height in header kToolbarHeight; ExtendedNestedScrollView( pinnedHeaderSliverHeightBuilder: () { return pinnedHeaderHeight; } ) ``` -------------------------------- ### Manage Inner Scrollables in ExtendedNestedScrollView Source: https://github.com/fluttercandies/extended_nested_scroll_view/blob/master/README.md This code snippet shows how to configure `ExtendedNestedScrollView` to manage scroll synchronization within its body, particularly when dealing with multiple inner scrollables in tab views. It highlights the use of `onlyOneScrollInBody` to control scroll position management, differentiating between `AutomaticKeepAliveClientMixin` and `PageStorageKey` strategies. ```dart ExtendedNestedScrollView( onlyOneScrollInBody: true, ) ``` -------------------------------- ### Implement Pull-to-Refresh in NestedScrollView Body (Dart) Source: https://context7.com/fluttercandies/extended_nested_scroll_view/llms.txt This Dart code snippet shows how to add pull-to-refresh to the body of an `ExtendedNestedScrollView`. It uses `PullToRefreshNotification` to handle the refresh logic and updates a `CustomScrollView` within a `TabBarView`. Dependencies include `extended_nested_scroll_view` and `pull_to_refresh_notification`. ```dart import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart'; import 'package:flutter/material.dart'; import 'package:pull_to_refresh_notification/pull_to_refresh_notification.dart'; class PullToRefreshExample extends StatefulWidget { @override _PullToRefreshExampleState createState() => _PullToRefreshExampleState(); } class _PullToRefreshExampleState extends State with TickerProviderStateMixin { late TabController tabController; int itemCount = 30; DateTime lastRefreshTime = DateTime.now(); @override void initState() { super.initState(); tabController = TabController(length: 2, vsync: this); } @override Widget build(BuildContext context) { final double statusBarHeight = MediaQuery.of(context).padding.top; final double pinnedHeaderHeight = statusBarHeight + kToolbarHeight; return Scaffold( body: ExtendedNestedScrollView( pinnedHeaderSliverHeightBuilder: () => pinnedHeaderHeight, headerSliverBuilder: (context, innerBoxIsScrolled) { return [ SliverAppBar( pinned: true, expandedHeight: 200.0, title: Text('Pull to Refresh'), flexibleSpace: FlexibleSpaceBar( background: Container(color: Colors.blue), ), ), ]; }, body: Column( children: [ TabBar( controller: tabController, labelColor: Colors.blue, tabs: [Tab(text: 'List 1'), Tab(text: 'List 2')], ), Expanded( child: TabBarView( controller: tabController, children: [ PullToRefreshNotification( color: Colors.blue, maxDragOffset: 100.0, onRefresh: () async { await Future.delayed(Duration(seconds: 2)); setState(() { itemCount += 10; lastRefreshTime = DateTime.now(); }); return true; }, child: CustomScrollView( physics: ClampingScrollPhysics(), slivers: [ SliverList( delegate: SliverChildBuilderDelegate( (context, index) { return ListTile( title: Text('Item $index'), subtitle: Text('Last refresh: $lastRefreshTime'), ); }, childCount: itemCount, ), ), ], ), ), ListView.builder( key: PageStorageKey('List2'), itemCount: 50, itemBuilder: (context, index) { return ListTile(title: Text('Item $index')); }, ), ], ), ), ], ), ), ); } @override void dispose() { tabController.dispose(); super.dispose(); } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.