Flutter - How can I design List Tile & List View - flutter

This is the result that I want.
This is the current output that I have.
How can I achieve this result specifically the lines that are present in between the list tiles? I am using a ListView to show the rules. Below is the code for the ListTile that I am using.
Widget ruleTile(String title) {
return ListTile(
contentPadding: EdgeInsets.zero,
leading: Image.asset(
"assets/images/sun.png",
width: 40.w,
),
title: Text(
title,
style: MyTextStyle.littlesmaller,
),
);
}

You can use Stack and dotted_line package combo to create something like that:
Stack(children: [
DottedLine(
direction: Axis.vertical,
lineLength: linelength,
lineThickness: 1.0,
)
// You ListTile Code
],)

Thanks to #pmatatias comment, I figured it out. This is the updated code I used to get the desired output.
Widget ruleTile(String title, num index) {
Widget connector = const DashedLineConnector(
color: Color(0xFFFACC15),
gap: 3,
);
return TimelineTile(
node: TimelineNode(
indicator: Image.asset(
"assets/images/sun.png",
width: 40.w,
),
startConnector: index == 0 ? null : connector,
endConnector: index == rulesList.length - 1 ? null : connector,
),
nodeAlign: TimelineNodeAlign.start,
contents: ListTile(
contentPadding: EdgeInsets.zero,
title: Text(
title,
style: MyTextStyle.littlesmaller,
),
),
);
}

Related

Fill the available space in Listtile

I am new to the flutter and trying to fill the empty space in the listtile. I tried to use dense and visualDensity but with that, I am not getting the required result. Any support and suggestions will be appreciated.
here is my code and output:
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
SizedBox(
height: isLargeScreen ? 300 : 200,
child: ListView.builder(
physics: const ScrollPhysics(),
shrinkWrap: true,
itemCount: tags.length,
itemBuilder: (context, index) {
return CheckboxListTile(
value: tempSelectedTags.contains(tags[index].id),
onChanged: (e) {
setState(() {
if (tempSelectedTags.contains(tags[index].id)) {
tempSelectedTags.remove(tags[index].id);
} else {
tempSelectedTags.add(tags[index].id);
}
});
},
title: Text(
tags[index].name,
style: !tempSelectedTags.contains(tags[index].id)
? theme.textTheme.labelMedium?.copyWith(
color: ThemeConfig.colorTertiary)
: theme.textTheme.titleSmall?.copyWith(
color: ThemeConfig.colorTertiary),
),
);
}),
),
const Spacer(),
Padding(
padding: const EdgeInsets.only(bottom:sdPaddingMedium),
child: SdPrimaryButton(
title: appLocalizations.btnApply,
onPressed: () {
viewModel.setTags(tempSelectedTags);
Navigator.pop(context);
},
),
),
],
)
Output can be seen here
There are two important things that determine the vertical layout in your column.
The whole box has a fixed size
SizedBox(
height: isLargeScreen ? 300 : 200,
There is a flexible space between the checkbox options and the bottom-right button
const Spacer(),
So if you want to remove the space, you can either
reduce the overall box size or
replace the const Spacer with a constant spacing like
SizedBox(height: 50) and also remove the SizedBox, so that the whole box will be content-sized

How to set the listview trailing padding

I am using listview.builder to show the api data, i want to set the text padding, here is the output
i want to set the approved and not approved text after the date.
here is my code
ListTile(
leading: CircleAvatar(
radius: 25,
backgroundColor:snapshot.data[index].type=="Sick"?Color(int.parse(annualboxcolor)):Color(int.parse(maternityboxcolor)),
child: Container(
padding: EdgeInsets.fromLTRB(0, 10, 0, 0),
child:Column(children: <Widget>[
Text(snapshot.data[index].noofdays.toString(),style: TextStyle(fontSize: 15.0,fontWeight: FontWeight.bold,color:Colors.white),),
Text(int.parse(snapshot.data[index].noofdays)>1?"Days":"Day",style: TextStyle(fontSize: 10.0,color:Colors.white),)
]
),
)),
title: Text(snapshot.data[index].type),
subtitle: Text(snapshot.data[index].fromdate+" To "+snapshot.data[index].todate),
trailing: Text(snapshot.data[index].Status=="ON"?"Approved":"Not Approved"),),
Container(padding: EdgeInsets.fromLTRB(80, 55, 0, 0),
child:Text(snapshot.data[index].Status=="ON"?"Approved":"Not Approved",
style: TextStyle(color:snapshot.data[index].Status=="ON"?Colors.green:Colors.red ),),),
i used container and set its padding but i want to do this in listtile
Instead using trailing, set isThreeLine to true, that makes the ListTile to display 3 lines of text instead of 2. After that, make subtitle a two line string with the data and the approved state, something like this:
ListTile(
// your existing code
isThreeLine: true,
// concatenate you strings, this is just an example,
// mind the `\n`, it makes new line
subtitle: Text("2021-02-02 To 2021-03-03\nNot Approved"),
// don't use trailing
// trailing:
)
If you need different styling, there is another way, using a Column in subtitle, and add separate Text widgets:
ListTile(
// ...
isThreeLine: true,
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("2021-02-02 To 2021-03-03",
style: TextStyle(color: Colors.green)),
Text("Not Approved",
style: TextStyle(color: Colors.red))
],
)
)
Try below code hope it's helpful to you use isThreeLine instead of trailing
ListTile(
leading: CircleAvtar(
child:Text('Sick'),
),
title: Text('Sick'),
subtitle:Text('Your Date\n Approved'),
isThreeLine:true,
),

Need to accomodate gridView in my flutter

Im building an app that shows diets and also have a search bar to look for the diets.
I cant manage accomodate the search bar correctly like outside the gridviewer. heres the code of my view and how it actually looks. I dont want to be like another card
body: Container(
child: GridView.builder(
padding: EdgeInsets.all(15),
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
itemCount: dietsForDisplay.length + 1,
itemBuilder: (BuildContext context, int index) {
if (diets.length == 0) {
return Container(
child: Padding(
padding: const EdgeInsets.all(60.0),
child: Text(
"No existen Dietas registradas por la nutriĆ³loga.",
style: TextStyle(
color: Color(0xFF002D53),
fontFamily: 'Montserrat',
fontSize: 25,
fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
),
),
);
} else {
return index == 0
? _searchBar()
: _listItem(
context,
index - 1,
);
}
}),
));
}
and the code for the searchBar and listItem are Cards
Wrap your material app inside a Safe Area Widget
https://api.flutter.dev/flutter/widgets/SafeArea-class.html
I would suggest you to wrap your Scaffold widget with SafeArea so that your appbar won't get obstructed due to the notch. If you would want to add a search bar in your Scaffold's body, I would suggest using a Column to place your search bar on the top and your GridView.builder() on the bottom. Here is how it looks like after my suggestions:
SafeArea(
child:Scaffold(
body: Column(
children: <Widget>[
//Search Bar here
Expanded(
child: //GridView.builder() here
);
],
),
),
);
*If you want that page to be scrollable then replace Column with ListView

How to use item count in ListView.Builder?

Click Here for Image! Click here to see error when i input 'itemCount' I want to ask, I am having trouble using the List.builder () feature. where I can't limit the data contained in the list so that it will display an error message about the error range. Here is the source code that I gave.
_sort = <Sort>[
Sort(
category: 'By Games',
item: new Container(
height: 200,
child: new Container(
child: ListView.builder(
scrollDirection: Axis.vertical,
//itemCount: allGames['games'].length,
itemBuilder: (context, index) {
return Container(
child: Padding(
padding: const EdgeInsets.all(15),
child: Text(allGames['games'][index]['game_title'].toString(), style: new TextStyle(color: Colors.white)),
),
);
},
)))),
and here i call the 'Category' and 'Item'. I wrap it in a wrap widget. then for categories, I did divide it into 3 parts. then every part in the category I named 'items' and the problem is the items here have excess capacity so that the data displayed is leftover and not on target.
child: Wrap(
children: <Widget>[
ListView.builder(
shrinkWrap: true,
itemCount: 3,
itemBuilder: (context, index) {
context = context;
if (index < 2) {
final sort = _sort[index];
return ExpansionTile(
title: ListTile(
title: Text(
sort.category,
style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold),
),
),
children: <Widget>[
ListTile(
title: sort.item,
)
],
);
} else {
),
You're accessing allGames["games"] and it says that you're trying to use [] on null.
Seems like allGames is null, so put an eye on that.
Other than that, your use of itemCount is fine!
You can add some null awareness by doing something like this:
itemCount = allGames != null ? (allGames["games"]?.length ?? 0) : 0
I think when the build method runs at the first time, your allGames is null. So, try to add a default value, for example:
itemCount: allGames['games'].length ?? 0

Flutter - How to create a vertical line between two widgets

I need to create a vertical line between two widgets like this: https://imgur.com/a/22ybF6o
I could do it but for a fixed size. If this size changes, layout got messy like this: https://imgur.com/a/kO9NXlJ
Here's my code:
Widget listItem(TripsData item) {
var startDate = DateFormat('dd/MM/yy - HH:mm').format(DateTime.parse(item.start));
var endDate = DateFormat('dd/MM/yy - HH:mm').format(DateTime.parse(item.end));
return Card(
child: Stack(
children: <Widget>[
drawDestinationLine(Colors.red),
Column(
children: <Widget>[
ListTile(
leading: drawDestinationCircle('A', Colors.blue),
title: Text(startDate),
subtitle: Text(item.locationStart),
),
const Padding(padding: EdgeInsets.only(bottom: 2.0)),
ListTile(
leading: drawDestinationCircle('B', Colors.blue),
title: Text(endDate),
subtitle: Text(item.locationEnd),
),
],
),
],
),
);
}
Does someone have a solution to help me with this?
Let me know if need more code, but StackOverflow didn't let me put more code here..
I used the package timelines 0.1.0 which makes this easily possible
Check on pub.dev and the corresponding Github repo for nice examples.
One of the sample use-cases looks like what you are looking for:
In this case you should use the Stack, Positioned, and ConstrainedBox widgets to create the desired arrangement.
Something like this pseudocode, you will need to supply correct coordinates:
Stack ( children: [
Positioned ( left: 0.0 , top : 0.0 , child:
ListTile (leading: drawDestinationCircle('A', Colors.blue),
title: Text(startDate),
subtitle: Text(item.locationStart),
)),
Positioned ( left: 0.0 , bottom : 0.0 , child:
ListTile (leading: drawDestinationCircle('B', Colors.blue),
title: Text(endDate),
subtitle: Text(item.locationEnd),
)),
Positioned ( left 20.0 , top : 20.0
, child: ConstrainedBox(
constraints: new BoxConstraints(
minHeight: 5.0,
minWidth: 5.0,
maxHeight: 30.0,
maxWidth: 5.0,
),
child: new DecoratedBox(
decoration: new BoxDecoration(color: Colors.red),
)
),
)
]);