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,
)));
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:
- Can't add Container or SizedBox "outside" ListTile, it will slow down when showing long list.
- ListTile is needed for showing then faster, adding widgets without ListTile will slow down.
- 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.