Flutter - Expandable - 如何在更改状态时保持面板展开

Alv*_*mar 4 flutter flutter-layout

我正在使用可扩展包(https://pub.dev/packages/expandable),当我在点击复选框时调用 setState () 方法时,可扩展面板会在小部件树重建期间关闭。

当我调用 setState () 时,我告诉控制器保持面板展开expController.expanded = true,但这不起作用。

我研究过,在我看来,解决方案是使用密钥,但我的测试不起作用。

有人能帮我吗?我需要更改复选框的状态,但保持面板展开。这是我的代码的示例:

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),
                        ),
                      );
                    },
                  ),
                ),
              ],
            ),
          ),
        ));
  }
}
Run Code Online (Sandbox Code Playgroud)

小智 5

抱歉,已经很晚了,但是当我在我的应用程序中使用可扩展时,我才知道:

您可以通过首先创建一个 ExpandableController,然后为其分配一个静态 bool isOpened 来完成此操作(它需要是静态的,因为我们分配给 initialExpanded 的 bool 应该在构造此 ExpandableController 之前存在)。然后在 initState() 中,您必须向其中添加一个 addListener 来更改 isOpened 的值。因此,现在每当您点击可扩展对象时,侦听器都会侦听并更改 isOpened 的值,现在当树小部件重建此 isOpened 变量时,将具有可扩展对象的当前状态。

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,
);
Run Code Online (Sandbox Code Playgroud)