Scrollable ListView bleeds background color to adjacent widgets
Asked Answered
O

1

11

I'm looking to create a simple layout using a scrollable ListView, with an immovable header tile. I've placed the header tile and ListView into a Column, so the Header can be above the ListView without scrolling off the screen. However, when scrolling the ListView, my header tile seems to take on the color of whatever ListView tiles are scrolling "under" it.

On startup, the app looks like this:

On startup, the app looks like this

However if we scroll half a tile down, the green color of the list tiles appears to push out the red from the header. The text from the green tiles does not have the same problem, and is properly occluded by the header tile

After scrolling, the green from the ListTiles replaces the red in the header tile

Minimal code for reconstruction

void main() => runApp(MyTestApp2());

class MyTestApp2 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
          appBar: AppBar(
            title: Text("AppBar Header"),
          ),
          body: Column(children: <Widget>[
            ListTile(
              title: Center(child: Text("This Header Should be Red")),
              tileColor: Colors.redAccent,
            ),
            Expanded(child: ListView(
              children: List.generate(20, (int index) => "List Item $index")
                  .map((n) => ListTile(
                      title: Text(n.toString()),
                      tileColor: Colors.lightGreen))
                  .toList(),
            )),
          ])),
    );
  }
}

What is happening here? I could probably achieve this layout using different Widgets, but I would like to know Why is this color bleed effect occurring? How does it fit with the box layout model Flutter uses?

EDIT: The immediate problem can be solved by wrapping the red ListTile in a Container widget, and setting the color property to be red on that container, like this:

        Container(
          color: Colors.redAccent,
          child: ListTile(....

However I would still like to know what is going on in terms of the layout algorithm in the original code, if anybody knows. Shouldn't the existence of the header tile prevent our listview from pushing its elements into the area owned by the red ListTile?

Ordnance answered 9/6, 2021 at 22:23 Comment(2)
It is working fine for me no color bleeding is happening. check the image here [image]imgur.com/a/qhbgnAl. I've copied your code and ran it in my local. It is working fine. You can run the flutter doctor once and see flutter and dart is updatedYonita
Thank you for commenting. I have run flutter doctor and encountered no errors. I also verified that the error occurs with both Flutter Web and Flutter on (emulated) Android. My SDK version in pubspec.yaml is '>=2.12.0 <3.0.0'. If anybody knows what might cause the issue, I'm still very curious.Ordnance
F
35

Please try wrapping listTile with Material widget I do not know why but the tileColor is keeping alive under the widgets while scrolling down the color of the tile went under the widgets above. Wrapping the listTile with Material should fix that for some reason.

Material(
  child: ListTile(
    shape: RoundedRectangleBorder(
      borderRadius: BorderRadius.circular(10),
    ),
    tileColor:const Color.fromARGB(255, 247, 247, 247),
    leading: Icon(
      Icons.monetization_on_outlined,
      color: Theme.of(context).primaryColor,
      size: 50,
    ),
    title: Text(
      "Some Strings",
    ),
    subtitle: Text("Some Strings"),
    onLongPress: () {},
    onTap: () {},
  ),
)
Flunkey answered 17/9, 2021 at 15:56 Comment(2)
Thanks! I was able to confirm that placing a Material widget just above the ListView in my example, solves the problem.Ordnance
This seem like error related to this issueImmaculate

© 2022 - 2024 — McMap. All rights reserved.