Flutter — расширяемый — как сохранить панель расширенной при изменении состояния

#flutter #flutter-layout

#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),
                        ),
                      );
                    },
                  ),
                ),
              ],
            ),
          ),
        ));
  }
}
 

Ответ №1:

Извините, что уже очень поздно, но поскольку я использовал расширяемый в своем приложении, я узнал, что:

Вы можете сделать это, сначала создав ExpandableController, затем присвоив его initialExpanded статический bool isOpened (он должен быть статическим, потому что bool, который мы назначаем initialExpanded, должен присутствовать до создания этого 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,
);