Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter - Expandable - How to keep the panel expanded when changing the state

I am using the expandable package (https://pub.dev/packages/expandable), and when I call the setState () method when taping on a checkbox the expandable panel closes during the widget tree reconstruction.

When I call setState () I tell the controller to keep the panel expanded expController.expanded = true, but that doesn't work.

I researched and it seems to me that the solution would be to use a key, but my tests did not work.

Can someone help me? I need to change the state of the checkbox, but keep the panel expanded. Here is an sample from my code:

class ExpandableCard extends StatefulWidget {
  ExpandableCard({Key key}) : super(key: key);

  @override
  _ExpandableCardState createState() => _ExpandableCardState();
}

class _ExpandableCardState extends State<ExpandableCard> {
  var _value = false;

  @override
  Widget build(BuildContext context) {
    ExpandableController expController =
        new ExpandableController(initialExpanded: false);

    return ExpandableNotifier(
        controller: expController,
        child: Padding(
          padding: const EdgeInsets.all(2),
          child: Card(
            clipBehavior: Clip.antiAlias,
            child: Column(
              children: <Widget>[
                ScrollOnExpand(
                  scrollOnExpand: true,
                  scrollOnCollapse: false,
                  child: ExpandablePanel(
                    theme: const ExpandableThemeData(
                      headerAlignment: ExpandablePanelHeaderAlignment.center,
                      tapBodyToCollapse: false,
                      tapHeaderToExpand: true,
                      tapBodyToExpand: true,
                      hasIcon: true,
                    ),
                    header: Padding(
                      padding: EdgeInsets.all(10),
                      child: Text('HEADER'),
                    ),
                    collapsed: Padding(
                      padding: EdgeInsets.only(left: 4),
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Text('collapsed'),
                        ],
                      ),
                    ),
                    expanded: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: <Widget>[
                        for (var _ in Iterable.generate(3))
                          Padding(
                            padding: EdgeInsets.only(left: 2, bottom: 2),
                            child: Row(
                              children: [
                                Checkbox(
                                  value: _value,
                                  onChanged: (bool value) {
                                    setState(() {
                                      this._value = value;
                                      expController.expanded = true;
                                    });
                                  },
                                ),
                                Text('Checkbox'),
                              ],
                            ),
                          ),
                      ],
                    ),
                    builder: (_, collapsed, expanded) {
                      return Padding(
                        padding:
                            EdgeInsets.only(left: 10, right: 10, bottom: 10),
                        child: Expandable(
                          collapsed: collapsed,
                          expanded: expanded,
                          theme: const ExpandableThemeData(crossFadePoint: 0),
                        ),
                      );
                    },
                  ),
                ),
              ],
            ),
          ),
        ));
  }
}
like image 334
Alvimar Avatar asked Oct 13 '25 00:10

Alvimar


1 Answers

Sorry it is very late but as i was using expandable in my app then i came to know that:

You can do this by first making an ExpandableController, then assiging its initialExpanded a static bool isOpened (It needs to be static because the bool that we are assigning to initialExpanded should be present before the construction of this ExpandableController). Then in initState(), you have to add an addListener to it that will change the value of isOpened. So now whenever you will tap on the expandable, the listener will listen and will change the value of isOpened and now when the tree widget will reconstruct this isOpened variable will have the current state of the Expandable.

static bool isOpened=false;

ExpandableController additionalInfoController=ExpandableController(
    initialExpanded: isOpened,
  );

// do this in initState

additionalInfoController.addListener(()
     {
       isOpened=!isOpened;
     });

//Then assign this controller to the controller of ExpandablePanel like this

ExpandablePanel(
       controller: additionalInfoController,
);
like image 149
Abdullah Arshad Avatar answered Oct 14 '25 16:10

Abdullah Arshad