Repository navigation
ScrollBar moves slower than the mouse when dragging it to scroll #112072
Copy link
Copy link
Closed
Labels
P2Important issues not at the top of the work listImportant issues not at the top of the work lista: desktopRunning on desktopRunning on desktopf: scrollingViewports, list views, slivers, etc.Viewports, list views, slivers, etc.found in release: 3.3Found to occur in 3.3Found to occur in 3.3found in release: 3.4Found to occur in 3.4Found to occur in 3.4frameworkflutter/packages/flutter repository. See also f: labels.flutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onThe issue has been confirmed reproducible and is ready to work onr: fixedIssue is closed as already fixed in a newer versionIssue is closed as already fixed in a newer version
Description
This one is bit different from #111968. It happens with current main in cases where SliverList items extents keep increasing.
Main reason for this is that ScrollBar._updateScrollPosition adjusts viewport position by using relative scroll offset. In pathological cases like this the error keeps increasing to the point where not even overdrag is enough to reach end.
I'm wondering why ScrollBar is written like that. Setting pixels to minExtent + (absoluteScrollPosition * (maxExtent - minExtent)) would alleviate this (absoluteScrollPosition being in range of 0.0-1.0). But I'm not sure how this would work with overdrag.
import 'package:flutter/material.dart';
void main() {
runApp(const MaterialApp(
title: 'Flutter Demo',
home: MyHomePage(),
));
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: CustomScrollView(
slivers: [
SliverToBoxAdapter(
child: Container(
height: 2,
color: Colors.red,
),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) => Padding(
padding: const EdgeInsets.all(10),
child: Container(
color: Colors.green,
height: index.toDouble(),
),
),
childCount: 1000,
),
),
SliverToBoxAdapter(
child: Container(
height: 2,
color: Colors.red,
),
),
],
),
);
}
}Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
P2Important issues not at the top of the work listImportant issues not at the top of the work lista: desktopRunning on desktopRunning on desktopf: scrollingViewports, list views, slivers, etc.Viewports, list views, slivers, etc.found in release: 3.3Found to occur in 3.3Found to occur in 3.3found in release: 3.4Found to occur in 3.4Found to occur in 3.4frameworkflutter/packages/flutter repository. See also f: labels.flutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onThe issue has been confirmed reproducible and is ready to work onr: fixedIssue is closed as already fixed in a newer versionIssue is closed as already fixed in a newer version
Activity
knopp commentedon Sep 21, 2022
cc @Piinks, @TahaTesser
exaby73 commentedon Sep 22, 2022
Hello @knopp. I cannot reproduce this issue. When scrolling multiple times, I am still able to see the red lines. Could you please provide some more details? How do I reliably reproduce this issue and which version and/or platform is this reproducible for you? Thank you.
knopp commentedon Sep 22, 2022
Can you maximize window and retry? You should see that the scrollbar is getting further away from mouse cursor as you scroll down. If there is no space below the window you don't be able to reach the end.
exaby73 commentedon Sep 22, 2022
Right I noticed that behavior. I have to reset my mouse multiple times to scroll fully. Posting a full triage report in a few minutes. Thanks for the information :)
exaby73 commentedon Sep 22, 2022
Triage Report
Versions reproducible on
Stable (3.3.2)Master (3.4.0-19.0.pre.442)Info
Video
Code Sample
Flutter Doctor
flutter doctor -v(Stable)flutter doctor -v(Master)[-]Can't scroll through entire viewport using ScrollBar[/-][+]`ScrollBar` moves slower than the mouse when dragging it to scroll[/+]xu-baolin commentedon Sep 23, 2022
Actually, this is a performance issue of Flutter, when dragging the bar, building the sliver items will take a lot of time and cause frame loss.
Workaround,
set
CustomScrollView.cacheExtenttodouble.maxFinitecan work as you want.CC @Piinks
knopp commentedon Sep 23, 2022
That will cause Flutter to eagerly build and layout entire content of the SliverList. Currently SliverList has a problem that in order to scroll through it it needs to build and layout all items regardless of whether they are displayed, but this is not a solution. It's also a separate issue.
Piinks commentedon Sep 26, 2022
I don't think this is a scrollbar issue, it is likely more to do with the fact that when the children of the list have variable extents (like in the sample code above), Flutter estimates what the maximum extent is, and updates it as the list grows and it has more information to inform that estimate.
For this issue, it sounds like the scrollbar should perform some version of edge scrolling, where dragging it at the edge when it has not reached the end triggers the scroll position forward.
Or, the way we estimate the maximum scroll offset could be updated/changed/modified to allow the user to configure.
If the later, this is the issue to follow: #97676
knopp commentedon Sep 26, 2022
In my opinion the primary issue is that scroll position update is always relative. So the relative scrollbar movement gets translated according to current scroll extent estimation and added to scroll position. But scroll extent estimation, especially at the very beginning, is much worse than towards the end. But with current approach this is never really corrected.
I've been playing with scrollbars a bit and I had much better experience when settings scroll position directly to
pixels=minExtent + absoluteScrollPosition * (maxExtent - minExtent). That's because the further you scroll, the more accurate extent estimation would be.So for example towards the end, when you are at 95%, doing layout for
pixels = minExtent + 0.95 * (maxExtent - minExtent)will probably update geometry with a decently accuratemaxExtent.Repeat this couple of times (96, 97, 98, 99%) and the maxExtent should be very close to actual value.
After that, scrolling towards the very end, at
pixels = minExtent + 1.0 * (maxExtent - minExtent), you should be at the end of viewport. Without (or with minimal) edge scrolling.github-actions commentedon Nov 9, 2022
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of
flutter doctor -vand a minimal reproduction of the issue.