-
Notifications
You must be signed in to change notification settings - Fork 26.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Inconsistent scrolling behavior in nested ListViews #148024
Comments
Hi @darajava, please take a look at this #99207 (comment). You should try NestedScrollView as suggested there to see if it can solve your case. |
So far we didn't do this, because trackpad/touch scroll has physics/curving that depends on the current state of the scrollable. Not sure how well a simple fix would work where we don't claim the drag if already at max scroll extent. And don't have bouncing scrolling. I think in general this wasn't a priority, because nested scroll views are a very poor experience on mobile, where scrollable areas are implicit and assumed to be continuous and full-width. |
@huycozy I have tried to implement
@moffatman I take your point as I can't find any examples of any nested scrollbars in any of the apps that I use. Perhaps my UI does not follow standard practice.
This is exactly what happens on web (html web, not Flutter) |
@darajava Have you tried using Sample code of NotificationListener ideaimport 'dart:ui';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
ScrollPhysics physics = AlwaysScrollableScrollPhysics();
@override
Widget build(BuildContext context) {
return MaterialApp(
scrollBehavior: MyCustomScrollBehavior(),
home: Scaffold(
body: ListView(
children: [
for (int i = 0; i < 20; i++) ListItem(),
SizedBox(
height: 220,
child: NotificationListener(
onNotification: (notification) {
// check if reaches the end of the list
if (notification is ScrollEndNotification) {
if (notification.metrics.extentAfter == 0) {
print('End of list');
setState(() {
physics = NeverScrollableScrollPhysics();
});
}
}
return true;
},
child: ListView(
shrinkWrap: true,
physics: physics,
children: [
for (int i = 0; i < 20; i++) ListItem2(),
],
),
),
),
for (int i = 0; i < 20; i++) ListItem(),
],
),
));
}
}
class ListItem extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.red,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Item'),
),
);
}
}
class ListItem2 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.grey,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Item 2'),
),
);
}
}
class MyCustomScrollBehavior extends MaterialScrollBehavior {
@override
Set<PointerDeviceKind> get dragDevices => {PointerDeviceKind.touch, PointerDeviceKind.mouse, PointerDeviceKind.stylus, PointerDeviceKind.trackpad};
}
This sample is not complete because it's only for scrolling down to bottom; you also need to calculate for the case when scrolling up back to the top (depending on your desire). And I also see this will be a complex behavior that you need to spend much effort on this UX. I'm not sure which app/design you refer to, but if you can share the use case here on other apps, it would be helpful. |
Without additional information, we are unfortunately not sure how to resolve this issue. We are therefore reluctantly going to close this bug for now. |
Steps to reproduce
Expected results
Behaviour should be as on web on both:
ListView
Actual results
(correct behavior) On desktop web, when scrolling using the trackpad, the scroll correctly continues and the parent scrolls down after the gray area is scrolled to the end.
(incorrect behavior) On MacOS, when scrolling using the trackpad, it is not possible to keep scrolling the parent when reached the end of the gray area.
(incorrect behavior) When dragging on Web/MacOS/Android/iOS, it is not possible to keep scrolling the parent after reaching the end of the gray area.
Code sample
Code sample
Screenshots or Video
Needs sound to make sense as I do a voiceover.
Screenshots / Video demonstration
Screen.Recording.2024-05-09.at.00.08.21.mov
Logs
Logs
[Paste your logs here]
Flutter Doctor output
Doctor output
The text was updated successfully, but these errors were encountered: