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),
),
);
},
),
),
],
),
),
));
}
}
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,
);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With