Saturday, November 28, 2020

Flutter - Expendable list with ExpansionTile and ExpansionPanel

In mobile application, if you want to show items in a list with expandable feature. The expandable view is a way that show items in a vertically scrolling two level list. 

 

In this post, we going to create a Flutter application to display expendable list with the help of ExpansionTile and ExpansionPanel. The final output look like below:


ExpansionTile

The ExpansionTile widget help us to create a collapse or expansion view with features similar to ListTile. The ExpansionTile has the following properties:

  • title: The title will be the one item that will always display to the user. When user click upon this title, the Widget will expand to reveal the contents. 
  • children: It can hold any widget that you want to display as child of tile.
  • leading: You can display a icon to the left of the title.
  • trailing: You can display a icon to the right of the title.
  • backgroundColor: You can provide the background color to the entire Expanded Tile.


ExpansionPanelList

ExpansionPanelList has the following attributes similar to List Tile:
  • AnimationDuration: This property is used to define the time required to expand or collapse the tile. 
  • Children: This property takes the ExpansionPanel as a parameter which means ExpansionPanel will be used to create a hidden view and header. 
  • ExpansionCallback: This property works wherever the view expands or collapses.


ExpansionPanel

ExpansionPanel has the following attributes similar to List Tile:

  • HeaderBuilder: This property is used to design the visible part of the list or title of a row. 
  • Body: We can use any widget to expand and collapse. 
  • IsExpanded: This property indicates whether the panel is expanded or not.


Creating a new project

1. Create a new Flutter project from File ⇒ New Flutter Project with your development IDE.
2. Now start editing main.dart class as you can see, we have implemented our theme and devide screen in two part. One for

ExpansionPanel and another for ExpansionPanelList.

import 'package:flutter/material.dart';
import 'package:flutter_expend/expansionPanel.dart';
import 'package:flutter_expend/expansionTile.dart';

void main() {
runApp(MyApp());
}

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primaryColor: const Color(0xFF02BB9F),
primaryColorDark: const Color(0xFF167F67),
accentColor: const Color(0xFF167F67),
),
debugShowCheckedModeBanner: false,
home: Home(),
);
}
}

class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
'Developer Libs',
style: TextStyle(color: Colors.white),
),
centerTitle: true,
elevation: 0.0,
),
// backgroundColor: Colors.white,
body: Padding(
padding: const EdgeInsets.all(30.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[

Expanded(
child: Expansiontile(),
flex: 1,
),

Expanded(
child: Expansionpanel(),
flex: 1,
),
],
),
),
);
}
}



3. Now, create another file expansionTile.dart to display
Expansiontile widget childern.

import 'package:flutter/material.dart';

class Expansiontile extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Expansion Tile',style: TextStyle(color: Colors.white),),
),
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 30.0),
child: Column(
children: <Widget>[
SizedBox(height: 20.0),
ExpansionTile(
title: Text(
"Flutter",
style: TextStyle(fontSize: 18.0, fontWeight: FontWeight.bold),
),
children: <Widget>[
ExpansionTile(
title: Text(
'Android',
),
children: <Widget>[
ListTile(
title: Text('Room Database'),
)
],
),
ListTile(
title: Text('Ios'),
)
],
),
],
),
),
);
}
}

4. Here, we have last code snippet expansionPanel.dart of this demo.  It will display ExpansionPanelList widget childern.

import 'package:flutter/material.dart';

class Expansionpanel extends StatefulWidget {
Expansionpaneltate createState() => Expansionpaneltate();
}

class Expansionpaneltate extends State<Expansionpanel> {
List<ExpansionpanelItem> items = <ExpansionpanelItem>[
ExpansionpanelItem(
isExpanded: false,
title: 'Android',
content: Padding(
padding: EdgeInsets.all(20.0),
child: Column(children: <Widget>[
Text('Room Database'),
Text('Activity'),
Text('Service'),
Text('Work Manager'),
Text('Fragment'),
])),
leading: Icon(Icons.android_outlined)),
];

Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
"Expansion Panel List",
style: TextStyle(color: Colors.white),
),
),
body: ListView(
children: [
Padding(
padding: EdgeInsets.all(10.0),
child: ExpansionPanelList(
expansionCallback: (int index, bool isExpanded) {
setState(() {
items[index].isExpanded = !items[index].isExpanded;
});
},
children: items.map((ExpansionpanelItem item) {
return ExpansionPanel(
headerBuilder: (BuildContext context, bool isExpanded) {
return ListTile(
leading: item.leading,
title: Text(
item.title,
textAlign: TextAlign.left,
style: TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.w400,
),
));
},
isExpanded: item.isExpanded,
body: item.content,
);
}).toList(),
),
),
],
),
);
}
}

class ExpansionpanelItem {
bool isExpanded;
final String title;
final Widget content;
final Icon leading;

ExpansionpanelItem({this.isExpanded, this.title, this.content, this.leading});
}

 

If you have followed the above post carefully. You will be able to display ExpansionPanel and ExpansionPanelList childern with header as shown above. But if you are facing any problem to implement it and you have any quires, please feel free to ask it from comment section below.

 

Share:

Get it on Google Play

React Native - Start Development with Typescript

React Native is a popular framework for building mobile apps for both Android and iOS. It allows developers to write JavaScript code that ca...