Package selection guidance compiled from public package information, community data, and project usage.
An enhanced version of Flutter's NestedScrollView that provides overscroll support for both the nested and parent scroll views, ensuring a smooth and consistent scrolling experience across all platforms. It improves upon the default behavior by allowing natural overscroll effects in both layers, making it ideal for complex scrollable layouts like app bars with scrollable content beneath. The package is actively maintained and compatible with Android, iOS, Web, macOS, Windows, and Linux.
Use cases
Complex app bar layouts
Nested scrollable content with overscroll
Scrolling with parallax effects
Responsive UIs with layered scrolling
Hybrid scrollable interfaces
Key features
Overscroll support for both nested and parent scroll views
Seamless scrolling experience
Cross-platform compatibility
Improved scroll physics
Support for custom scroll behaviors
Active maintenance and updates
Suitable for
Developers building advanced scrollable UIs
Apps requiring layered scrolling with visual feedback
Projects needing consistent overscroll behavior
Teams targeting multiple platforms
UI designers implementing dynamic scroll effects
Considerations
May increase complexity for simple scroll layouts
Requires careful handling of scroll controllers
Potential performance impact with deeply nested scrolls
Not necessary for basic scrollable widgets
Best suited for advanced use cases over standard NestedScrollView
Original README
Original README snapshot from the linked source repository. Visit the repository for the latest content.
NestedScrollViewPlus
An enhanced NestedScrollView offering overscroll support for both the nested and parent scroll views, ensuring a seamless scrolling experience.
Install NestedScrollViewPlus by running the following command:
flutter pub add nested_scroll_view_plus
Here’s a basic example:
import'package:nested_scroll_view_plus/nested_scroll_view_plus.dart';
// Step 1: Replace `NestedScrollView` with `NestedScrollViewPlus`NestedScrollViewPlus(
headerSliverBuilder: (context, innerScrolled) => <Widget>[
// ... insert your header sliver widgets here
],
body: CustomScrollView(
// Step 2: [🚨IMPORTANT] Set the physics of `CustomScrollView` to `AlwaysScrollableScrollPhysics`
physics: constBouncingScrollPhysics(
parent: AlwaysScrollableScrollPhysics(),
),
slivers: <Widget>[
// ... insert your body sliver widgets here
],
),
);
For additional examples, please visit the scroll_master repository. It includes features such as pull-to-refresh for NestedScrollView, combined scrolling for scrollview and tabview, and more.
🚗 Examples
1. Loading Indicator
NestedScrollViewPlus(
overscrollBehavior: OverscrollBehavior.outer,
headerSliverBuilder: (context, innerScrolled) => <Widget>[
// Place the refresh indicator at the top of the header sliversCupertinoSliverRefreshControl(
onRefresh: () async {
// fetching data
},
),
// Add your custom AppBar or other header sliver widgets here.
],
// ...
)
2. Accessing the Inner or Outer Scroll Controller
To access the inner or outer scroll controller of a NestedScrollViewPlus, you can use a GlobalKey<NestedScrollViewStatePlus> to get its state.
👉 Example
class_ExampleStateextendsState<Example> {
// 1. Create a GlobalKeyfinalGlobalKey<NestedScrollViewStatePlus> myKey = GlobalKey();
@overrideWidgetbuild(BuildContext context) {
returnNestedScrollViewPlus(
// 2. Set the key to NestedScrollViewStatePlus
key: myKey,
// ...,
);
}
@overridevoidinitState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
// 3. Access the inner or outer scroll controller using GlobalKey<NestedScrollViewStatePlus>
myKey.currentState!.innerController.addListener(_handleInnerScroll);
myKey.currentState!.outerController.addListener(_handleOuterScroll);
});
}
void_handleInnerScroll() {
final innerController = myKey.currentState!.innerController;
if (innerController.positions.length == 1) {
print('Scrolling inner nested scrollview: ${innerController.offset}');
}
}
void_handleOuterScroll() {
final outerController = myKey.currentState!.outerController;
if (outerController.positions.length == 1) {
print('Scrolling outer nested scrollview: ${outerController.offset}');
}
}
}
3. Preserve Scroll Positions of Inner CustomScrollViews
To preserve the scroll positions of inner CustomScrollViews, you can add a PageStorageKey to the CustomScrollView widget. Here's an example:
By assigning a unique key to the CustomScrollView, Flutter's PageStorage mechanism will store and restore the scroll position of the inner CustomScrollViews, allowing you to maintain the scroll positions even when the widget tree is rebuilt.
⭕️ For Older Flutter Versions
If you are using an older version of Flutter, please follow these steps to install the appropriate branch from the old git repository.
dependencies:
custom_nested_scroll_view:
git:
url: https://github.com/idootop/custom_nested_scroll_view.git
# Choose the branch based on your local Flutter version
ref: flutter-3.7
The different branches support the following Flutter versions:
Git branch
Supported flutter versions
flutter-3.7
>=3.7.0-13.0.pre
flutter-3.4
>=3.4.0-27.0.pre <3.7.0-13.0.pre
flutter-3.4-pre
>=3.4.0-17.0.pre <3.4.0-27.0.pre
flutter-3.0
>=2.12.0-4.0.pre <3.4.0-17.0.pre
flutter-2.x
<2.12.0-4.0.pre
For more details, please visit the old documentation for CustomNestedScrollView.