In my Flutter application I need to display a list with one or two item cards per line accordingly to the property singleLine. If it's true, the item must be displayed in the whole line, if it's false then I need to check the next item. If both have singleLine as false, then I must display both in the same line, otherwise both will be displayed in separate lines using full width. For example, consider the following list:
final cards = [
{"title": "Item 1", "singleLine": true},
{"title": "Item 2", "singleLine": false},
{"title": "Item 3", "singleLine": false},
{"title": "Item 4", "singleLine": true},
{"title": "Item 5", "singleLine": true},
{"title": "Item 6", "singleLine": false},
{"title": "Item 7", "singleLine": true},
{"title": "Item 8", "singleLine": false},
{"title": "Item 9", "singleLine": false},
];
In this case I want to display this in the screen:
Item 1
Item 2 Item 3
Item 4
Item 5
Item 6
Item 7
Item 8 Item 9
How can I do this?
Answers
To achieve the desired layout in your Flutter application, you can use a ListView.builder
with a custom implementation for the item layout. Based on the singleLine
property of each item, you can conditionally decide how to display the items.
Here's how you can implement it:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('List with Custom Layout')),
body: ItemList(),
),
);
}
}
class ItemList extends StatelessWidget {
final cards = [
{"title": "Item 1", "singleLine": true},
{"title": "Item 2", "singleLine": false},
{"title": "Item 3", "singleLine": false},
{"title": "Item 4", "singleLine": true},
{"title": "Item 5", "singleLine": true},
{"title": "Item 6", "singleLine": false},
{"title": "Item 7", "singleLine": true},
{"title": "Item 8", "singleLine": false},
{"title": "Item 9", "singleLine": false},
];
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: cards.length,
itemBuilder: (context, index) {
final currentItem = cards[index];
final previousItem = index > 0 ? cards[index - 1] : null;
if (currentItem['singleLine'] ||
(previousItem != null && !previousItem['singleLine'])) {
// Display the item in full width if it's singleLine or if the previous item is not singleLine
return ListTile(
title: Text(currentItem['title']),
);
} else {
// Display two items in the same line
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Expanded(
child: ListTile(
title: Text(previousItem['title']),
),
),
Expanded(
child: ListTile(
title: Text(currentItem['title']),
),
),
],
);
}
},
);
}
}
In this code:
- We use a
ListView.builder
to dynamically create a list of items based on thecards
list. - Inside the
itemBuilder
, we check thesingleLine
property of each item and conditionally decide how to display it. - If an item's
singleLine
property istrue
, we display it in full width using aListTile
. - If an item's
singleLine
property isfalse
and the previous item'ssingleLine
property is alsofalse
, we display both items in the same line using aRow
widget withExpanded
widgets to ensure equal spacing. - Otherwise, if the previous item's
singleLine
property istrue
, we display the current item in full width.