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
ListView background overflows from parent Container #86584
Comments
|
I encountered the same issue. Here is a gist illustrating the problem - https://dartpad.dev/?id=4eebd5c2bf278a8ba2e2c0c7e9a269bf&null_safety=true Wrapping the 'ListTile' in a 'Container' with a background color of black does not make the issue go away. It just becomes more apparent! I also tried to wrap the 'ListView' in a 'ClipRect' and it did not solve the issue. This feels like it should be a fairly common problem meaning I must be missing something. Is there a simple fix for this? Edit: Just a suggestion for the flutter team - if the 'ListTile' expects a certain type of parent it would be nice if the framework threw an exception. |
|
Thank you for the suggestion! I still feel as though this is unexpected behaviour and should be resolved somehow since under no circumstance would I expect the background/foreground of a Widget to be clipped differently. |
|
I agree @ColonisationCaptain. FYI - it seems to not only be a problem with 'ListTile' but also other widgets such as 'InkWell' if the direct child of the list is not a 'Card'. |
|
Hi @ColonisationCaptain, Edited: This works fine on v2.0.0 and is broken on 2.0.1, so most probably it was broken on v2.0.1 code sampleOutput
flutter doctor -vThank you for your contribution. |
|
cc: @goderbauer |
|
I was able to isolate this is a little bit more. import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SizedBox(
height: 200,
child: ListView.builder(
itemCount: 12,
itemBuilder: (BuildContext context, int index) {
// Wrapping ListTile in a Card resolves this issue, but should not
// be necessary
return ListTile(
tileColor: index % 2 == 0 ? Colors.grey : null,
onTap: () {},
title: Text('List Item $index'),
);
},
),
),
),
);
}
}I also was able to bisect to the change that caused it: #76892 |
|
cc @NWalker1208 Looks like your change (#74373) is causing some clipping issues. Do you have time to take a look at it? It took me a bit to realize what the bug here is from the description, but if you scroll the view in the dartpad examples, you can see that although the list content isn't displayed outside the container, the ink is still drawing outside of the bounds of the parent container when it should be clipped. I think the reason that putting a import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Flutter Demo',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: SizedBox(
height: 200,
child: Material( // Just adding this fixes the issue
child: ListView.builder(
itemCount: 12,
itemBuilder: (BuildContext context, int index) {
return SizedBox(
height: 50,
child: ListTile(
tileColor: index.isEven ? Colors.grey : null,
hoverColor: Colors.red,
onTap: () {},
title: const Text(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
),
),
);
},
),
),
),
),
);
}
} |
|
Gotcha. It's been a while since I looked at the changes I made, but this makes sense based on what I remember. The ListTile was having issues with ink effects because its background was drawn on top of the Material widget that rendered the ink effects. We fixed that by making the background an ink decoration so it is rendered below the ink effects. But that seems to be causing issues when the Material widget that renders the background and effects is larger than the area that the tile should be clipped to. This issue was likely present before, but was less noticeable since only the ripple effects were being drawn instead of the background. I see two possible solutions. One, you could wrap the ListView's widget tree in a Material widget, which would then clip any ink decorations to the appropriate area. That's basically the workaround it sounds like they're using, but this would make it built in to the ListView. This would be a simple solution, but doesn't solve the larger problem of InkDecorations being clipped only based on the Material widget rather than whatever widget created them. You could also have the ListTile wrap itself in a Material widget, so that any clipping applied to it also applies to the ink effects it creates. If I understand right, though, Material widgets are more resource intensive, so it's generally encouraged to use as few of them as possible. Long term, there may need to be some way to have InkDecorations include information about how they should be clipped. I'm not sure how that could be implemented, and unfortunately I'm pretty busy now with school. Hopefully you all can find a workable solution, I'll try to chime in when I can. |
|
Thank you for the update @NWalker1208! This makes me think #88793 is related. |
|
I'm actually starting to think that this is "as intended", because ink is meant to be drawn on whatever material it is on top of, and we have plenty of places where you have to supply a Material widget in order to limit the spread of the ink to the desired area. I think the difference here is that the ink in question is the background color, not just an animated ink splash. So, if you want the background ink to only be drawn in the area of your widget, you have to supply a Material widget that limits it. I'm not saying it's totally intuitive the first time you encounter it, or that we shouldn't change the way it works, but it does give you more flexibility to have ink (especially ink splashes) draw outside the immediate widget that is being clicked (which is desirable for some design scenarios). |
|
It's also a "regression" in the sense that the behavior has now changed from the original implementation. |
|
First off I found a better solution that takes into account @NWalker1208's performance concerns in wrapping each child. The 'ListView' can simply be wrapped in a Material component. https://dartpad.dev/?id=e911a9f82de19eac8c7e70ccd3af599d&null_safety=true @gspencergoog - from my perspective (a dumb user), it would be more helpful if any scroll container were more consistently clipping it's content. For example, I would expect both the background and text to be clipped in this case - https://dartpad.dev/?id=2c242d875656a8e5f03cca6dde39e851&null_safety=true What if the viewport wrapped its children in a material component? |
Jumping into this as a confused flutter user without much context so sorry if this isn't helpful, but this feels like really strange and undesirable behavior for a background color. It makes total sense to me for something like an ink splash. What about just making list tile's background color behave like |
I'm facing an issue where I have constrained the height of a ListView (builder) widget with a Container, however the background colours of the contents of the ListView - ListTile widgets - are drawn outside the parent Container, as shown below.
Here is the code needed to reproduce the issue:
I have been able to reproduce the issue on both the stable and dev channels, but I have only attached logs from the stable channel. My system runs the
Microsoft Windows [Version 10.0.19043.1083]operating system.You can also view the issue in dartpad:
https://dartpad.dev/add807346cce557cd859364a2b843571
I think the following stackoverflow post also references this issue:
https://stackoverflow.com/questions/51211959/
However the 'solution' proposed is merely a workaround to the underlying issue, because in my case it breaks the expected hovering behaviour, as can be seen here, where I have implemented the workaround of setting the background colour of the Container instead of the ListTile:
https://dartpad.dev/22b2a05837b512e34e729c004b8afdde
Here, the red hovering indicator is not applied to the tiles coloured grey, which is not intended. It may be possible to work around this second issue once again by setting the red hovering indicator in the Container widget, but this is not a solution to the underlying issue with the ListTile widget.
Steps to Reproduce
flutter create garbage.flutter runand choose either the Windows or Web - Chrome option.Expected results:
I would expect for the background of the ListTile widgets to be constrained to the size of the parent Container, just like the contents of the ListTile widgets (the lorem ipsum text).
Actual results:
Logs
logs from the stable channel
flutter analyse
flutter doctor
flutter run --verbose on Windows first, then on Chrome (web)
The text was updated successfully, but these errors were encountered: