Flutter - ExpansionTile double actions - flutter

Is it possible to configure a ExpansationTile to have 2 actions:
Expand when clicking on the trailing icon
Going to another screen when clicking anywhere else?
Also, is it possible to omit the trailing icon IF the children of the item doesn't have information to display (eg, sublist is empty)?
Here's what I have ATM:
Expanded(
child: ListView.builder(
itemBuilder: (context, index) {
return Card(
child: ExpansionTile(
leading: Image.asset('images'),
title: Text('Text'),
subtitle: Text('Text'),
children: [
ListView.builder(
itemBuilder: (context, index2) {
return Card(
child: ListTile(
onTap: () => print('test'),
leading: Image.asset('images'),
title: Text('Text'),
subtitle: Text('Text'),
);
},
itemCount: list[index].sublist.length,
shrinkWrap: true,
padding: EdgeInsets.all(5),
scrollDirection: Axis.vertical,
),
],
),
);
},
itemCount: list.length,
shrinkWrap: true,
padding: EdgeInsets.all(5),
scrollDirection: Axis.vertical,
),
)

You can achieve it by adding IconButton to the trailing part of the ExpansionTile.
Here's an example code snippet for the same.
ExpansionTile(
title: const Text('Hello'),
trailing: IconButton(
onPressed: () => log('Hello');
icon: const Icon(Icons.arrow_drop_down),
),
children: const [Text('World')],
),

Related

Working with Tap function within LIstView

I was testing the "tap function" for items within a ListView, but it does not seem to work. The print function does not work when I tap upon the list.
return Scaffold(
appBar: AppBar(
// App Bar
title: Text(
"ListView On-Click Event",
style: TextStyle(color: Colors.grey),
),
elevation: 0,
backgroundColor: Colors.white,
),
// Main List View With Builder
body: ListView.builder(
itemCount: imgList.length,
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
print("button pressed");
print(index);
},
child: Container(
margin: const EdgeInsets.symmetric(
vertical: 2.0,
horizontal: 8.0,
),
child: Stack(
children: <Widget>[
cardDesign,
cardImage,
],
),
),
); // gesturedetector
}));
Where am I going wrong?
Try to used Column instead of Stack
ListView.builder(
shrinkWrap: true,
itemCount: 10,
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
print("button pressed");
print(index);
},
child: Container(
margin: const EdgeInsets.symmetric(
vertical: 2.0,
horizontal: 8.0,
),
child: Column(
children: <Widget>[
Text(index.toString()),//put your widgets here
],
),
),
); // gesturedetector
}),
you can use ListTile inside ListView,because ListTile have onTap function, same here :
ListView.builder(
itemCount: data.length,
itemBuilder: (BuildContext context, int index) {
return Card(
child: ListTile(
title: Text('TextHere'),
onTap: () {
log('on tap');
},
),
);
});

Flutter listview scrolling is not available

I can see 6 list items in my listview widget and I can not scroll the listview although 3 more items are there.
Actually I want to keep this workouts page pretty simple that means I want to avoid using many rows/columns...
I have just a text label at the top left corner and below listview.
What do I have to change to make the listview scrolling?
I already use physics: AlwaysScrollableScrollPhysics(),
appBar: AppBar(
title: Text(title),
),
body: Container(
color: Colors.green,
margin: const EdgeInsets.all(5.0),
child: Column(
children: [
Align(
alignment: Alignment.topLeft,
child: Text("Workouts", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 25)),
),
Expanded(
child: ListView.builder(
physics: AlwaysScrollableScrollPhysics(),
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: workouts.length,
itemBuilder: (context, index) {
var workout = workouts[index];
return WorkoutWidget(key: Key(workout.id.toString()), workout: workout);
}),
),
],
),
),
Change physics to NeverScrollableScrollPhysics(), then wrap your Container with SingleChildScrollView widget. You could also omit scrollDirection, because Axis.vertical is already the default value.
appBar: AppBar(
title: Text(title),
),
body: SingleChildScrollView(
child: Container(
color: Colors.green,
margin: const EdgeInsets.all(5.0),
child: Column(
children: [
Align(
alignment: Alignment.topLeft,
child: Text(
"Workouts",
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 25),
),
),
Expanded(
child: ListView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: workouts.length,
itemBuilder: (context, index) {
var workout = workouts[index];
return WorkoutWidget(
key: Key(workout.id.toString()),
workout: workout,
);
}),
),
],
),
),

ItemList in an ItemList not scrolling

I have a nested ItemList that is made as follows:
SafeArea(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
ListTile(
title: Text('Placeholder'),
),
ListView.builder(
shrinkWrap: true,
itemCount: itemList.length,
itemBuilder: (BuildContext context, int index) {
final itemData = itemList[index];
return Card(
child: ListTile(
title: Container(
width: MediaQuery.of(context).size.width,
child: Text(
itemData.text,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: Theme.of(context).textTheme.headline5,
),
),
),
);
},
),
],
),
),
I can scroll up and down when holding the items directly placed in the first list, doing so also moves the items from the nested list. (wanted behavior)
When holding items in the sublist (the one with the builder), nothing moves anywhere.
I want to make so that all items move when any of them are held to scroll, how can I do that?
Is there a way to build a list without ListView.builder or did I miss some ListView parameters?
You could use the physics parameter of Listview to achive the intended result.
SafeArea(
child: ListView(
physics: AlwaysScrollableScrollPhysics(), // add this
padding: EdgeInsets.zero,
children: <Widget>[
ListTile(
title: Text('Placeholder'),
),
ListView.builder(
physics: NeverScrollableScrollPhysics(), // and this
shrinkWrap: true,
itemCount: itemList.length,
itemBuilder: (BuildContext context, int index) {
final itemData = itemList[index];
return Card(
child: ListTile(
title: Container(
width: MediaQuery.of(context).size.width,
child: Text(
itemData.text,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: Theme.of(context).textTheme.headline5,
),
),
),
);
},
),
],
),
)
Now your list should be scrollable.

ExpansionTile is overflowing

I am trying to wrap some list items in an Expansion panel But the contents are overflowing.
ExpansionTile(
title: Text('Client'),
children: <Widget>[
ListView(
scrollDirection: Axis.vertical,
shrinkWrap: true,
children: <Widget>[
ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: upComingCompliancesList.length,
itemBuilder: (BuildContext context,int index){
return Container(
margin: EdgeInsets.symmetric(vertical: 10.0),
color: buttonColor,
child: ListTile(
title: Text(upComingCompliancesList[index].name==null? upComingCompliancesList[index].name==null : ' '),
subtitle: Text(
'${upComingCompliancesList[index].label} at ${upComingCompliancesList[index].date}'),
),
);
},
),
],
),
],
),
It is showing the following error:
The following assertion was thrown during layout:
A RenderFlex overflowed by 277 pixels on the bottom.
the following error is shown on the screen:
Try wrapping your ExpansionTile in a scrollable Widget to compensate for its content when the ExpansionTile is in an expanded state. Use 'SingleChildScrollView' like so:
SingleChildScrollView(
child: ExpansionTile(
title: Text('Client'),
children: <Widget>[
ListView(
scrollDirection: Axis.vertical,
shrinkWrap: true,
children: <Widget>[
ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: upComingCompliancesList.length,
itemBuilder: (BuildContext context,int index){
return Container(
margin: EdgeInsets.symmetric(vertical: 10.0),
color: buttonColor,
child: ListTile(
title: Text(upComingCompliancesList[index].name==null? upComingCompliancesList[index].name==null : ' '),
subtitle: Text(
'${upComingCompliancesList[index].label} at ${upComingCompliancesList[index].date}'),
),
);
},
),
],
),
],
),
),

How to add dynamic content in ExpansionTile on drawer?

I need to add a ListViewBuilder in ExpansionTile. The expansion tile in the left side drawer. Im new in flutter, i dont know how to add this ? Please help me to fix this ?
drawer: Drawer(
child: Container(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
ListTile(......),
ListTile(......),
ListTile(......),
ExpansionTile(
title: Text(
'Game Rules',
style: TextStyle(color: Colors.white),
),
leading: new IconButton(
icon: new Icon(
Icons.wb_iridescent,
color: Colors.white,
),
),
children: <Widget>[
ListView.builder(
itemCount: _rules.length,
itemBuilder: (context, index) {
return Text(_rules[index]['category']);
})
],
),
]
In your ListView.builder - add - shrinkWrap: true,
ListView.builder(
shrinkWrap: true, // Add this
itemCount: _rules.length,
// itemCount: 10,
itemBuilder: (context, index) {
return Text(_rules[index]['category']);
// return Text('$index');
})