ExpansionPanel Widget – Flutter Guide By Flutter Agency

· 5 min read
ExapansionPanel
ExapansionPanel

Flutter has a really good widget to achieve expand/collapse functionality. It has ExpansionPanelList & ExpansionPanel to create an expand/collapse view. As we know in Flutter everything is a widget and hence Flutter ExpansionPanel is also a widget that you can use like other Flutter widgets.

What is ExpansionPanel Widget?

ExpansionPanel Widget is a list that shows its children using expansion animation on click of item.

The constructor of ExpansionPanel will look like below :

 ExpansionPanelWidget({
    Key key,
    List<ExpansionPanel> children: const [],
    ExpansionPanelCallback expansionCallback,
    Duration animationDuration: kThemeAnimationDuration,
    EdgeInsets expandedHeaderPadding: _kPanelHeaderExpandedDefaultPadding,
  });

Properties :

  • expansionCallBack : expansionCallBack gets called whenever the expand/collapsed button is pressed on any of the items inside the list. It gives us two things.
  1. Index of the clicked item
  2. Whether to expand or collapsed the item clicked.
  • children : ExpansionPanel Widget is used as a child for the ExpansionPanelList. This widget has got below properties.
  1. headerBuilder: Used to show the header of the item.
  2. body: Used to show the details of the item when expanded.
  3. isExpanded: This is very important as it decides whether to expand/collapsed the item or not. Defaults to false.
  4. canTapOnHeader: Be default, You have to click on ^ icon to expand but you can pass true to this property to also make header of the item clickable
  • animationDuration: Used to define the duration in which the expand and collapsed animation should complete. It defaults to 200ms.

However, it is recommended to keep it to the original you can still change it to anything like this.

animationDuration: Duration(milliseconds: 300),

Example :

Create a prepareData Array that will hold the data for the item. bool isExpanded will be used to determine whether the item needs to expand or not.

List<ItemModel> prepareData = <ItemModel>[
  ItemModel(
    header: 'Milk',
    bodyModel: BodyModel(price: 20, quantity: 10),
  ),
  ItemModel(
    header: 'Coconut',
    bodyModel: BodyModel(price: 35, quantity: 5),
  ),
  ItemModel(
    header: 'Watch',
    bodyModel: BodyModel(price: 800, quantity: 15),
  ),
  ItemModel(
    header: 'Cup',
    bodyModel: BodyModel(price: 80, quantity: 150),
  )
];

Prepare a list of items using Code Snippet as below :

headerBuilder: (BuildContext context, bool isExpanded) {
                    return Container(
                      padding: EdgeInsets.all(10),
                      child: Text(
                        prepareData[index].header,
                        style: TextStyle(
                          color: Colors.black54,
                          fontSize: 18,
                        ),
                      ),
                    );
                  },
isExpanded: prepareData[index].isExpanded,

 On receiving expansionCallback change the isExpanded parameter of the item inside the list of books and rebuild a widget.

expansionCallback: (int item, bool status) {
                setState(() {
                  prepareData[index].isExpanded =
                      !prepareData[index].isExpanded;
                });
              },

The complete Source code will look like below :

import 'package:flutter/material.dart';
import 'package:multiImagePicker/model/item_model.dart';

class ExpansionPanelWidget extends StatefulWidget {
  @override
  _ExpansionPanelWidgetState createState() => _ExpansionPanelWidgetState();
}

List<ItemModel> prepareData = <ItemModel>[
  ItemModel(
    header: 'Milk',
    bodyModel: BodyModel(price: 20, quantity: 10),
  ),
  ItemModel(
    header: 'Coconut',
    bodyModel: BodyModel(price: 35, quantity: 5),
  ),
  ItemModel(
    header: 'Watch',
    bodyModel: BodyModel(price: 800, quantity: 15),
  ),
  ItemModel(
    header: 'Cup',
    bodyModel: BodyModel(price: 80, quantity: 150),
  )
];

class _ExpansionPanelWidgetState extends State<ExpansionPanelWidget> {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Container(
        padding: EdgeInsets.all(10),
        child: ListView.builder(
          itemCount: prepareData.length,
          itemBuilder: (BuildContext context, int index) {
            return ExpansionPanelList(
              animationDuration: Duration(seconds: 1),
              children: [
                ExpansionPanel(
                  body: Container(
                    padding: EdgeInsets.all(10),
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      children: <Widget>[
                        Text(
                          'PRICE: ${prepareData[index].bodyModel.price}',
                          style: TextStyle(
                            color: Colors.grey[700],
                            fontSize: 18,
                          ),
                        ),
                        Text(
                          'QUANTITY: ${prepareData[index].bodyModel.quantity}',
                          style: TextStyle(
                            color: Colors.grey[700],
                            fontSize: 18,
                          ),
                        )
                      ],
                    ),
                  ),
                  headerBuilder: (BuildContext context, bool isExpanded) {
                    return Container(
                      padding: EdgeInsets.all(10),
                      child: Text(
                        prepareData[index].header,
                        style: TextStyle(
                          color: Colors.black54,
                          fontSize: 18,
                        ),
                      ),
                    );
                  },
                  isExpanded: prepareData[index].isExpanded,
                )
              ],
              expansionCallback: (int item, bool status) {
                setState(() {
                  prepareData[index].isExpanded =
                      !prepareData[index].isExpanded;
                });
              },
            );
          },
        ),
      ),
    );
  }
}

In the above code snippet, we have used a ListView Widget. We will get output like below:

Expansion Panel

ExpansionPanel List

Thanks for being with us !!!

Keep reading !!!

FlutterAgency.com is our portal Platform dedicated to Flutter Technology and Flutter Developers. The portal is full of cool resources from Flutter like Flutter Widget Guide, Flutter Projects, Code libs and etc.

FlutterAgency.com is one of the most popular online portal dedicated to Flutter Technology and daily thousands of unique visitors come to this portal to enhance their knowledge on Flutter.

Leave a Reply