idootop / custom_nested_scroll_view Goto Github PK
View Code? Open in Web Editor NEWA Flutter NestedScrollView that supports outer scroller to top overscroll.
Home Page: https://flutter-nested-scroll-view-plus.vercel.app
License: MIT License
A Flutter NestedScrollView that supports outer scroller to top overscroll.
Home Page: https://flutter-nested-scroll-view-plus.vercel.app
License: MIT License
: Warning: Operand of null-aware operation '!' has type 'SchedulerBinding' which excludes null.
the current version of the code is not compatible with flutter 3.7
I'm getting ane error (Xcode):
../../../.pub-cache/git/custom_nested_scroll_view-74a3a7163278c8e84
18ba359d94f6448196d0b25/lib/src/nested_scroll_view.dart:526:24:
Error: The method '_NestedScrollMetrics.copyWith' doesn't have the
named parameter 'devicePixelRatio' of overridden method 'Object
with ScrollMetrics.copyWith'.
I have no issues on stable.
I'm using Flutter master branch, and I just pulled the lastest update and try starting my app, however I got an error from this plugin file.
My Flutter and Dart version info is below:
Flutter 3.7.0-13.0.pre.79 • channel master • https://github.com/flutter/flutter.git
Framework • revision 91c3f80c8c (15 hours ago) • 2022-12-27 04:44:24 -0500
Engine • revision 790604a09f
Tools • Dart 3.0.0 (build 3.0.0-64.0.dev) • DevTools 2.20.0
And in this version of Flutter, after I tried to start my app, I got this error (I tried flutter clean and pub get however the problem still there):
Launching lib\main.dart on sdk gphone64 x86 64 in debug mode...
lib\main.dart:1
: Error: The method '_NestedScrollMetrics.copyWith' doesn't have the named parameter 'devicePixelRatio' of overridden method 'Object with ScrollMetrics.copyWith'.
../…/src/nested_scroll_view.dart:526
_NestedScrollMetrics copyWith({
^
/C:/flutter/packages/flutter/lib/src/widgets/scroll_metrics.dart:43:17: Context: This is the overridden method ('copyWith').
ScrollMetrics copyWith({
^
: Error: The superclass, 'FixedScrollMetrics', has no unnamed constructor that takes no arguments.
../…/src/nested_scroll_view.dart:514
_NestedScrollMetrics({
^^^^^^^^^^^^^^^^^^^^
Target kernel_snapshot failed: Exception
2
FAILURE: Build failed with an exception.
* Where:
Script 'C:\flutter\packages\flutter_tools\gradle\flutter.gradle' line: 1157
* What went wrong:
Execution failed for task ':app:compileFlutterBuildDebug'.
> Process 'command 'C:\flutter\bin\flutter.bat'' finished with non-zero exit value 1
* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 16s
Exception: Gradle task assembleDebug failed with exit code 1
Exited (sigterm)
When user overscrolls, a layout exception is thrown
══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
The following assertion was thrown during performLayout():
SliverGeometry is not valid: The "scrollExtent" is negative.
The RenderSliver that returned the offending geometry was: _RenderSliverOverlapAbsorberX#c28e4 relayoutBoundary=up1 NEEDS-PAINT:
needs compositing
creator: CustomSliverOverlapAbsorber ← _ProfileSliverAppBar ← BlocListener<AuthWatcherCubit,
AuthWatcherState> ← BlocSelector<AuthWatcherCubit, AuthWatcherState, User?> ←
_NestedScrollViewViewport ← IgnorePointer-[GlobalKey#eb7c8] ← Semantics ← Listener ←
_GestureSemantics ← RawGestureDetector-[LabeledGlobalKey<RawGestureDetectorState>#e565b] ←
Listener ← _ScrollableScope ← ⋯
parentData: paintOffset=Offset(0.0, 0.0) (can use size)
constraints: SliverConstraints(AxisDirection.down, GrowthDirection.forward, ScrollDirection.forward,
scrollOffset: 0.0, remainingPaintExtent: 748.0, overlap: -148.0, crossAxisExtent: 414.0,
crossAxisDirection: AxisDirection.right, viewportMainAxisExtent: 896.0, remainingCacheExtent:
998.0, cacheOrigin: 0.0)
geometry: SliverGeometry(scrollExtent: -0.0, paintExtent: 296.0, paintOrigin: -148.0, layoutExtent:
148.0, maxPaintExtent: 296.0, hasVisualOverflow: true, cacheExtent: 148.0)
handle: _SliverOverlapAbsorberHandle(0.0null)
The relevant error-causing widget was:
CustomSliverOverlapAbsorber
CustomSliverOverlapAbsorber:file:///Users/brendan/Mobile/FlutterProjects/sorosoke/lib/features/dashboard/presentation/screens/profile_sc
reen.dart:125:12
When the exception was thrown, this was the stack:
#0 SliverGeometry.debugAssertIsValid.<anonymous closure>.verify (package:flutter/src/rendering/sliver.dart:712:9)
#1 SliverGeometry.debugAssertIsValid.<anonymous closure> (package:flutter/src/rendering/sliver.dart:721:7)
#2 SliverGeometry.debugAssertIsValid (package:flutter/src/rendering/sliver.dart:751:6)
#3 RenderSliver.debugAssertDoesMeetConstraints (package:flutter/src/rendering/sliver.dart:1205:22)
#4 RenderObject.layout.<anonymous closure> (package:flutter/src/rendering/object.dart:2138:9)
#5 RenderObject.layout (package:flutter/src/rendering/object.dart:2140:8)
#6 RenderViewportBase.layoutChildSequence (package:flutter/src/rendering/viewport.dart:516:13)
#7 RenderViewport._attemptLayout (package:flutter/src/rendering/viewport.dart:1600:12)
#8 RenderViewport.performLayout (package:flutter/src/rendering/viewport.dart:1507:20)
#9 RenderObject._layoutWithoutResize (package:flutter/src/rendering/object.dart:1973:7)
#10 PipelineOwner.flushLayout (package:flutter/src/rendering/object.dart:999:18)
#11 RendererBinding.drawFrame (package:flutter/src/rendering/binding.dart:513:19)
#12 WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:884:13)
#13 RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:378:5)
#14 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1175:15)
#15 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1104:9)
#16 SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:1015:5)
#20 _invoke (dart:ui/hooks.dart:150:10)
#21 PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:318:5)
#22 _drawFrame (dart:ui/hooks.dart:115:31)
(elided 3 frames from dart:async)
The following RenderObject was being processed when the exception was fired: _RenderSliverOverlapAbsorberX#c28e4 relayoutBoundary=up1
NEEDS-PAINT:
needs compositing
creator: CustomSliverOverlapAbsorber ← _ProfileSliverAppBar ← BlocListener<AuthWatcherCubit,
AuthWatcherState> ← BlocSelector<AuthWatcherCubit, AuthWatcherState, User?> ←
_NestedScrollViewViewport ← IgnorePointer-[GlobalKey#eb7c8] ← Semantics ← Listener ←
_GestureSemantics ← RawGestureDetector-[LabeledGlobalKey<RawGestureDetectorState>#e565b] ←
Listener ← _ScrollableScope ← ⋯
parentData: paintOffset=Offset(0.0, 0.0) (can use size)
constraints: SliverConstraints(AxisDirection.down, GrowthDirection.forward, ScrollDirection.forward,
scrollOffset: 0.0, remainingPaintExtent: 746.7, overlap: -149.3, crossAxisExtent: 414.0,
crossAxisDirection: AxisDirection.right, viewportMainAxisExtent: 896.0, remainingCacheExtent:
996.7, cacheOrigin: 0.0)
geometry: SliverGeometry(scrollExtent: -1.3, paintExtent: 297.3, paintOrigin: -149.3, layoutExtent:
148.0, maxPaintExtent: 297.3, hasVisualOverflow: true, cacheExtent: 148.0)
handle: _SliverOverlapAbsorberHandle(0.0null)
This RenderObject had the following descendants (showing up to depth 5):
child: _RenderSliverPinnedPersistentHeaderForWidgets#10042 relayoutBoundary=up2 NEEDS-PAINT
child: RenderSemanticsAnnotations#f31e0 relayoutBoundary=up3 NEEDS-PAINT
child: RenderAnnotatedRegion<SystemUiOverlayStyle>#434e1 relayoutBoundary=up4 NEEDS-PAINT
child: RenderPhysicalModel#bf5d5 relayoutBoundary=up5 NEEDS-PAINT
child: _RenderInkFeatures#eba97 relayoutBoundary=up6 NEEDS-PAINT
════════════════════════════════════════════════════════════════════════════════════════════════════
Another exception was thrown: SliverGeometry is not valid: The "scrollExtent" is negative.
Another exception was thrown: SliverGeometry is not valid: The "scrollExtent" is negative.
Another exception was thrown: SliverGeometry is not valid: The "scrollExtent" is negative.
Another exception was thrown: SliverGeometry is not valid: The "scrollExtent" is negative.
Another exception was thrown: SliverGeometry is not valid: The "scrollExtent" is negative.
Another exception was thrown: SliverGeometry is not valid: The "scrollExtent" is negative.
Another exception was thrown: SliverGeometry is not valid: The "scrollExtent" is negative.
Another exception was thrown: SliverGeometry is not valid: The "scrollExtent" is negative.
Another exception was thrown: SliverGeometry is not valid: The "scrollExtent" is negative.
Another exception was thrown: SliverGeometry is not valid: The "scrollExtent" is negative.
Another exception was thrown: SliverGeometry is not valid: The "scrollExtent" is negative.
Another exception was thrown: SliverGeometry is not valid: The "scrollExtent" is negative.
Another exception was thrown: SliverGeometry is not valid: The "scrollExtent" is negative.
Another exception was thrown: SliverGeometry is not valid: The "scrollExtent" is negative.
Another exception was thrown: SliverGeometry is not valid: The "scrollExtent" is negative.
Another exception was thrown: SliverGeometry is not valid: The "scrollExtent" is negative.
Another exception was thrown: SliverGeometry is not valid: The "scrollExtent" is negative.
Another exception was thrown: SliverGeometry is not valid: The "scrollExtent" is negative.
Another exception was thrown: SliverGeometry is not valid: The "scrollExtent" is negative.
Another exception was thrown: SliverGeometry is not valid: The "scrollExtent" is negative.
Another exception was thrown: SliverGeometry is not valid: The "scrollExtent" is negative.
Another exception was thrown: SliverGeometry is not valid: The "scrollExtent" is negative.
Another exception was thrown: SliverGeometry is not valid: The "scrollExtent" is negative.
Another exception was thrown: SliverGeometry is not valid: The "scrollExtent" is negative.
Another exception was thrown: SliverGeometry is not valid: The "scrollExtent" is negative.
Another exception was thrown: SliverGeometry is not valid: The "scrollExtent" is negative.
Another exception was thrown: SliverGeometry is not valid: The "scrollExtent" is negative.
Another exception was thrown: SliverGeometry is not valid: The "scrollExtent" is negative.
Another exception was thrown: SliverGeometry is not valid: The "scrollExtent" is negative.
Another exception was thrown: SliverGeometry is not valid: The "scrollExtent" is negative.
Another exception was thrown: SliverGeometry is not valid: The "scrollExtent" is negative.
Another exception was thrown: SliverGeometry is not valid: The "scrollExtent" is negative.
Another exception was thrown: SliverGeometry is not valid: The "scrollExtent" is negative.
Another exception was thrown: SliverGeometry is not valid: The "scrollExtent" is negative.
Another exception was thrown: SliverGeometry is not valid: The "scrollExtent" is negative.
Another exception was thrown: SliverGeometry is not valid: The "scrollExtent" is negative.
Another exception was thrown: SliverGeometry is not valid: The "scrollExtent" is negative.
Use the default example in the Readme.md
minHeight
to 100maxHeight
to 120ScrollView
past 120 (maxHeight)class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: DefaultTabController(
length: 2,
child: CustomNestedScrollView(
overscrollType: CustomOverscroll.outer,
// !important
physics: const BouncingScrollPhysics(
parent: AlwaysScrollableScrollPhysics(),
),
headerSliverBuilder: (context, innerScrolled) => <Widget>[
MySliverAppBar(),
],
body: TabBarView(
children: [
CustomScrollView(
// !important
physics: const BouncingScrollPhysics(
parent: AlwaysScrollableScrollPhysics(),
),
slivers: <Widget>[
TopOverlapInjector(),
// scroll view
SliverFixedExtentList(
delegate: SliverChildBuilderDelegate(
(_, index) => ListTile(
key: Key('$index'),
title: Center(
child: Text('ListTile ${index + 1}'),
),
),
childCount: 30,
),
itemExtent: 50,
),
],
),
CustomScrollView(
physics: NeverScrollableScrollPhysics(),
slivers: <Widget>[
TopOverlapInjector(),
// some widget
SliverFillRemaining(
child: Center(
child: Text('Test'),
),
),
],
),
],
),
),
),
);
}
}
class TopOverlapInjector extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Builder(
builder: (context) => CustomSliverOverlapInjector(
overscrollType: CustomOverscroll.outer,
handle: CustomNestedScrollView.sliverOverlapAbsorberHandleFor(context),
),
);
}
}
class MySliverAppBar extends StatelessWidget {
///Header collapsed height
final minHeight = 100.0;
///Header expanded height
final maxHeight = 120.0;
final tabBar = TabBar(
tabs: <Widget>[Text('Tab1'), Text('Tab2')],
);
@override
Widget build(BuildContext context) {
final topHeight = MediaQuery.of(context).padding.top;
return CustomSliverOverlapAbsorber(
overscrollType: CustomOverscroll.outer,
handle: CustomNestedScrollView.sliverOverlapAbsorberHandleFor(
context,
),
sliver: SliverAppBar(
pinned: true,
stretch: true,
toolbarHeight: minHeight - tabBar.preferredSize.height - topHeight,
collapsedHeight: minHeight - tabBar.preferredSize.height - topHeight,
expandedHeight: maxHeight - topHeight,
flexibleSpace: FlexibleSpaceBar(
centerTitle: true,
title: Center(child: Text('Example')),
stretchModes: <StretchMode>[
StretchMode.zoomBackground,
StretchMode.blurBackground,
],
background: Image.network(
'https://pic1.zhimg.com/80/v2-fc35089cfe6c50f97324c98f963930c9_720w.jpg',
fit: BoxFit.cover,
),
),
bottom: tabBar,
),
);
}
}
There are some breaking changes in the API of flutter 3.4:
ScrollActivityDelegate
has a new method updateBallisticAnimation
which must be implementedBallisticScrollActivity
has a new parameter in its constructor: shouldIgnorePointer
Has someone already looked into this?
Using the example you provided I changed the list to build two Items.
In this case the list should not scroll.
import 'package:flutter/material.dart';
import 'package:custom_nested_scroll_view/custom_nested_scroll_view.dart';
void main() => runApp(
MaterialApp(
title: 'Example',
home: Example(),
),
);
class Example extends StatefulWidget {
const Example({Key? key}) : super(key: key);
@override
State<Example> createState() => _ExampleState();
}
class _ExampleState extends State<Example> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: DefaultTabController(
length: 2,
child: CustomNestedScrollView(
// use key to access CustomNestedScrollViewState
key: myKey,
headerSliverBuilder: (context, innerScrolled) => <Widget>[
// use CustomOverlapAbsorber to wrap your SliverAppBar
CustomOverlapAbsorber(
sliver: MySliverAppBar(),
),
],
body: TabBarView(
children: [
CustomScrollView(
slivers: <Widget>[
// use CustomOverlapInjector on top of your inner CustomScrollView
CustomOverlapInjector(),
_tabBody1,
],
),
CustomScrollView(
slivers: <Widget>[
// use CustomOverlapInjector on top of your inner CustomScrollView
CustomOverlapInjector(),
_tabBody2,
],
),
],
),
),
),
);
}
final GlobalKey<CustomNestedScrollViewState> myKey = GlobalKey();
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
// use GlobalKey<CustomNestedScrollViewState> to access inner or outer scroll controller
myKey.currentState?.innerController.addListener(() {
final innerController = myKey.currentState!.innerController;
print('>>> Scrolling inner nested scrollview: ${innerController.positions}');
});
myKey.currentState?.outerController.addListener(() {
final outerController = myKey.currentState!.outerController;
print('>>> Scrolling outer nested scrollview: ${outerController.positions}');
});
});
}
final _tabBody1 = SliverFixedExtentList(
delegate: SliverChildBuilderDelegate(
(_, index) => ListTile(
key: Key('$index'),
title: Center(
child: Text('ListTile ${index + 1}'),
),
),
childCount: 2,
),
itemExtent: 50,
);
final _tabBody2 = const SliverFillRemaining(
child: Center(
child: Text('Test'),
),
);
}
class MySliverAppBar extends StatelessWidget {
///Header collapsed height
final minHeight = 120.0;
///Header expanded height
final maxHeight = 400.0;
final tabBar = const TabBar(
tabs: <Widget>[Text('Tab1'), Text('Tab2')],
);
@override
Widget build(BuildContext context) {
final topHeight = MediaQuery.of(context).padding.top;
return SliverAppBar(
pinned: true,
stretch: true,
toolbarHeight: minHeight - tabBar.preferredSize.height - topHeight,
collapsedHeight: minHeight - tabBar.preferredSize.height - topHeight,
expandedHeight: maxHeight - topHeight,
flexibleSpace: FlexibleSpaceBar(
centerTitle: true,
title: const Center(child: Text('Example')),
stretchModes: <StretchMode>[
StretchMode.zoomBackground,
StretchMode.blurBackground,
],
background: Image.network(
'https://pic1.zhimg.com/80/v2-fc35089cfe6c50f97324c98f963930c9_720w.jpg',
fit: BoxFit.cover,
),
),
bottom: tabBar,
);
}
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.