An expandable list responds to user gesture by expanding and shrinking its size, typically to show and hide a sublist
expandable
package can be used to implement an expandable list
Each list item and its functionality to expand to show its sublist can be implemented using a ExpandablePanel
component wrapped inside a ScrollOnExpand
component so that the app can get scrolled when item is pressed
The outer list containing the expandable items can be added as a child of ExpandableTheme
widget
Check Flutter installation to setup Flutter
Use flutter create
command to create a Flutter project (here expandable_list_app :
flutter create expandable_list_app
Add expandable
package to pubspec.yaml
dependencies:
expandable: "^4.1.4"
flutter:
sdk: flutter
Run following command to add dependency
flutter pub get
import 'package:expandable/expandable.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Expandable List App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: ExpandableListPage(),
);
}
}
class ExpandableListPage extends StatelessWidget {
var array = [
{
'expanded': false, 'category_Name': "Mobiles", 'sub_Category': [{ 'id': 1, 'name': 'Mi' }, { 'id': 2, 'name': 'RealMe' }, { 'id': 3, 'name': 'Samsung' },
{ 'id': 4, 'name': 'Infinix' }, { 'id': 5, 'name': 'Oppo' }, { 'id': 6, 'name': 'Apple' }, { 'id': 7, 'name': 'Honor' }]
},
{
'expanded': false, 'category_Name': "Laptops", 'sub_Category': [{ 'id': 8, 'name': 'Dell' }, { 'id': 9, 'name': 'MAC' }, { 'id': 10, 'name': 'HP' },
{ 'id': 11, 'name': 'ASUS' }]
},
{
'expanded': false, 'category_Name': "Computer Accessories", 'sub_Category': [{ 'id': 12, 'name': 'Pendrive' }, { 'id': 13, 'name': 'Bag' },
{ 'id': 14, 'name': 'Mouse' }, { 'id': 15, 'name': 'Keyboard' }]
},
{
'expanded': false, 'category_Name': "Home Entertainment", 'sub_Category': [{ 'id': 16, 'name': 'Home Audio Speakers' },
{ 'id': 17, 'name': 'Home Theatres' }, { 'id': 18, 'name': 'Bluetooth Speakers' }, { 'id': 19, 'name': 'DTH Set Top Box' }]
},
{
'expanded': false, 'category_Name': "TVs by brand", 'sub_Category': [{ 'id': 20, 'name': 'Mi' },
{ 'id': 21, 'name': 'Thomson' }, { 'id': 22, 'name': 'LG' }, { 'id': 23, 'name': 'SONY' }]
},
{
'expanded': false, 'category_Name': "Kitchen Appliances", 'sub_Category': [{ 'id': 24, 'name': 'Microwave Ovens' },
{ 'id': 25, 'name': 'Oven Toaster Grills (OTG)' }, { 'id': 26, 'name': 'Juicer/Mixer/Grinder' }, { 'id': 27, 'name': 'Electric Kettle' }]
}
];
ListView generateItems() {
return ListView.separated(
shrinkWrap:true,
itemCount: array.length,
itemBuilder: (BuildContext context, int index) {
return ExpandableWidget(array[index]);
},
separatorBuilder: (BuildContext context, int index) => const Divider(),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Expandable List Example"),
),
body: ExpandableTheme(
data: ExpandableThemeData(iconColor: Colors.blue, useInkWell: false),
child: generateItems(),
),
);
}
}
class ExpandableWidget extends StatelessWidget {
var subcategoryList;
var category;
ExpandableWidget(entry){
category = entry['category_Name'];
subcategoryList = entry['sub_Category'];
}
@override
Widget build(BuildContext context) {
buildHeader() {
return Builder(
builder: (context) {
var controller = ExpandableController.of(context);
return Container(
width:double.infinity,
height: 50.0,
alignment: Alignment.center,
child: Stack(
children:[
Container(
width:double.infinity,
alignment: Alignment.centerLeft,
child : Text(category,
style: Theme.of(context).textTheme.button.copyWith(
color: Colors.deepPurple
),
),
),
Container(
width:double.infinity,
height:double.infinity,
child: FlatButton(
onPressed: () {
controller.toggle();
},
),
),
]
),
);
},
);
}
buildExpanded() {
return ListView.separated(
shrinkWrap:true,
physics: const NeverScrollableScrollPhysics(),
itemCount: subcategoryList.length,
itemBuilder: (BuildContext context, int index) {
var subcategoryName = subcategoryList[index]['name'];
return Container(
height: 30,
child: Padding(
padding: const EdgeInsets.only(left: 10,),
child: Text('${subcategoryName}')
),
);
},
separatorBuilder: (BuildContext context, int index) => const Divider(),
);
}
return ExpandableNotifier(
child: Container(
color: Colors.amber[600],
padding: const EdgeInsets.only(left: 10.0, right: 0, bottom: 0),
child: ScrollOnExpand(
child:
ExpandablePanel(
header: buildHeader(),
expanded: buildExpanded(),
),
),
)
);
}
}
Ensure a supported device is connected or emulator/simulator is started
Go to project directory
Use flutter run
command to run
flutter run
It builds and runs app on an available android/ios device