Home > Enterprise >  How to make ListTile zero height
How to make ListTile zero height

Time:06-02

I'm trying to build a ListView with ListTile

Code here :

List<bool> isRed2 = [
   true,true,false,false,
   true,true,true,false,
   false,false,true,true,
   false,true,true,true,
   true,];

 return ListView.builder(
    padding: EdgeInsets.all(0),
    scrollDirection: Axis.vertical,
    shrinkWrap: true,
    itemCount: isRed2.length,
    itemBuilder: (context, i) => ListTile(
        dense: true,
        minVerticalPadding: 0,
        contentPadding: EdgeInsets.all(0),
        minLeadingWidth: 0,
        horizontalTitleGap: 0,
        title: isRed2[i]
            ? Container(
                height: 50,
                color: Colors.red,
              )
            : Container(
                height: 1,
                color: Colors.blue,
              )));

And result looks like:enter image description here

I set those elements which value is false height = 1 but they still have lots of space.

Any idea how to set height to match widget or skip those value is false?

Problems:

  1. Can't add Container or SizedBox "outside" ListTile, it will slow down when showing long list.
  2. ListTile is needed for showing then faster, adding widgets without ListTile will slow down.
  3. Copy elements which value is "true" to new list and build by it is not a good idea for my situation.

CodePudding user response:

Try to set visualDensity read more about ListTile

ListTile(
    contentPadding: EdgeInsets.zero,
    dense: true,
    visualDensity: VisualDensity(vertical: -4),
    title: Text('ListTile'),
),

CodePudding user response:

ListTiles should visually be at most 32 (dense: true) or 40 (dense: false) in height,

It will get the default height based on scenario. Instead of using ListTile use Column and row if needed.

return ListView.builder(
    padding: EdgeInsets.all(0),
    scrollDirection: Axis.vertical,
    itemCount: isRed2.length,
    itemBuilder: (context, i) => isRed2[i]
        ? Container(
            height: 50,
            color: Colors.red,
          )
        : Container(
            height: 1,
            color: Colors.blue,
          ));

Adding SizedBox "outside" ListTile doesnt cost any performance issue as much as I am aware of, you can remove shrinkWrap: true instead, you can check this video on SrinkWarp.

You can wrap ListTile with SizedBox.

return ListView.builder(
    padding: EdgeInsets.all(0),
    scrollDirection: Axis.vertical,
    itemCount: isRed2.length,
    itemBuilder: (context, i) => SizedBox(
          height: isRed2[i] ? 50 : 1,
          child: ListTile(
            tileColor: isRed2[i] ? Colors.red : Colors.blue,
          ),
        ));

Also check sliver for performance.

CodePudding user response:

First of all, VisualDensity is to set how compact your list tile is going to be, it won't make the height zero. You can not have a List Tile with zero height.

in list_tile.dart file (the implementation of list tile) at line 1071, you can see this :

  double get _defaultTileHeight {
    final bool hasSubtitle = subtitle != null;
    final bool isTwoLine = !isThreeLine && hasSubtitle;
    final bool isOneLine = !isThreeLine && !hasSubtitle;

    final Offset baseDensity = visualDensity.baseSizeAdjustment;
    if (isOneLine)
      return (isDense ? 48.0 : 56.0)   baseDensity.dy;
    if (isTwoLine)
      return (isDense ? 64.0 : 72.0)   baseDensity.dy;
    return (isDense ? 76.0 : 88.0)   baseDensity.dy;
  }

and if you track it, you finally see this:

size = constraints.constrain(Size(tileWidth, tileHeight));
assert(size.width == constraints.constrainWidth(tileWidth));
assert(size.height == constraints.constrainHeight(tileHeight));

which means it's not going to have zero-height also, the first line in the list tile doc in here is:

A single fixed-height row that typically contains some text as well as a leading or trailing icon.

  • Related