-
Notifications
You must be signed in to change notification settings - Fork 28.6k
Fix scrollbar margins #107172
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
Fix scrollbar margins #107172
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should _trackExtent
in the getTrackToScroll
be replaced with traversable extent?
Yes! Good catch. This is exactly the kind of thing I am trying to make more consistent to avoid future bugs in the larger clean up PR. I'll fix it here. |
@@ -568,15 +568,15 @@ class ScrollbarPainter extends ChangeNotifier implements CustomPainter { | |||
1.0); | |||
|
|||
// Scrollbar thumb respects margin, track paints full length. | |||
final double traversibleTrackExtent = _trackExtent - (2 * mainAxisMargin); | |||
final double traversableTrackExtent = _trackExtent - (2 * mainAxisMargin); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll wrap this up in a getter in the larger refactor that will follow this.
There are also some edge cases to confirm:
flutter/packages/flutter/lib/src/widgets/scrollbar.dart Lines 560 to 564 in 90d3b9d
I don't quite understand why we need to subtract the value of padding here, what do you think? We can not assume that the content view applies to the paddings. import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
scrollBehavior: MaterialScrollBehavior().copyWith(scrollbars: false),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: MediaQuery(
data: MediaQuery.of(context).copyWith(
padding: EdgeInsets.all(50),
),
child: RawScrollbar(
mainAxisMargin: 0,
crossAxisMargin: 0,
trackVisibility: true,
thumbVisibility: true,
thickness: 20,
thumbColor: Colors.black,
trackColor: Colors.yellowAccent,
trackBorderColor: Colors.pink,
child: Column(
children: [
Center(
child: SizedBox(
height: 300,
child: CustomScrollView(
primary: true,
slivers: [
SliverList(
delegate: SliverChildBuilderDelegate(
(c, i) => Container(
height: 50,
child: Center(child: Text('Item $i'))),
childCount: 12,
),
)
],
),
),
),
Container(height: 20, color: Colors.green)
],
),
),
),
);
}
}
|
@@ -1342,15 +1352,20 @@ class RawScrollbar extends StatefulWidget { | |||
/// {@macro flutter.widgets.Scrollbar.scrollbarOrientation} | |||
final ScrollbarOrientation? scrollbarOrientation; | |||
|
|||
/// Distance from the scrollbar's start and end to the edge of the viewport | |||
/// in logical pixels. It affects the amount of available paint area. | |||
/// Distance from the scrollbar thumb's start or end to the nearest edge of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ScrollbarPainter.mainAxisMargin
's docs can update too.
Thank you so much for identifying these! I am following up on them and will have something back tomorrow. 🙏 |
I think it makes sense for that margin area of the track to be interactive. The hit testing uses the rects created for the track and thumb. So if you tap on the margin that is contained within the track, I think it makes sense that the track would respond.
Done
I agree! This is something I have been wondering too, it's part of the larger clean up I have a WIP PR on. I just split up the changes so that 1) they are easier to review and 2) I would know I did not break anything with the larger refactor with the new tests. For the sample app that you have above, it does look off, but in other cases, like when there is a notch or the status bar area, the padding needs to be respected - like in #106834 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
I'm still a little worried about the impact of this change. First, there is a area where the thumb cannot reach in the main axle, which will mislead that the scrollable has not rolled to the edge of the view. Second, if we support buttons at both ends in the future, this margin area will be even more strange. |
This is actually the default for the Cupertino scrollbar, it has default margins such that the scrollbar never reaches the end of the perceived track area.
That is likely something we would address then, since this is currently hypothetical, we can't really account for it right now. |
Agh the bot was too fast for me. @xu-baolin if you have string feelings about this and would like to discuss further, we can revert this. |
The Cupertino scrollbar doesn't have track color, right? |
Considering that we have a 2D bar with track color, we need to configure margin in one corner to avoid crossover. It doesn't seem to be possible now, right? |
The motivation for this change was the inconsistently in how margins were being handled. The cross axis margin applied to the thumb, and not the track, and so it seemed logical for the margin in the main axis to reflect the same behavior. Would the padding sample you demonstrated above better handle the 2D case you mention? I don't know that the main axis margin makes sense from an api standpoint to pad the scrollbar. Perhaps padding should be exposed on the scrollbar instead of only using the MediaQueryData above it. It would give the user more control in a way that makes sense. We can certainly do that in a follow up change along with the clean up. Also - we've been looking into and official 2D scrolling solution that would support 2D scrollbars. It's not quite ready yet, but I am optimistic that in this case it will just work, and not require extra configuring by the user. |
Totally agree. |
LGTM |
Fixes #106918
This makes it such that the margins of the main and cross axes are treated the same way.
The track paints the full extent, while the margins are only applied to the thumb.
This is part of a yak shave in the scrollbar, as part of another proposal I found some bugs and code rot. I am fixing these all individually so that the proposal is not muddied with bugs fixes and new features mixed together.
Pre-launch Checklist
///
).If you need help, consider asking for advice on the #hackers-new channel on Discord.