退出 showModalBottomSheet 并再次显示 showModalBottomSheet 时,Flutter 无法保留状态

Flutter can't preserve stateful state when exit showModalBottomSheet and show showModalBottomSheet again

所以我有下面的代码来显示ModalBottomSheet,并在页面上显示filters/checkboxes。如果我退出模式并再次显示 showModalBottomSheet,那么我看不到复选框值被保留。

好像是第2次显示modal,又调用了_CheckboxStatefulWidgetState的build(),然后默认checkValue为null。

这里是filter.dart

import 'package:flutter/material.dart';
import '../helper/checkbox.dart';

mixin ListFilter<T extends StatefulWidget> on State<T> {

  dynamic filters = [
    {
      "name": "name1",
      "choices": [
        {'label': 'label1', 'value': 'value1', 'check': false},
        {'label': 'label2', 'value': 'value2', 'check': false},
      ],
    },
    {
      "name": "nameA",
      "choices": [
        {'label': 'labelA', 'value': 'valueA', 'check': false},
        {'label': 'labelB', 'value': 'valueB', 'check': false},
      ],
    },
  ];

  dynamic filterWidgets;

  void showFilterModal(context, dynamic filters) {
    showModalBottomSheet<void>(
      context: context,
      //isScrollControlled: true,
      builder: (BuildContext context) {
        if (filterWidgets == null) {
          print("----> filterWidgets is null");
          filterWidgets = _getFilterWidgets(filters);
        }
        return Container(
          child: Center(
            child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: filterWidgets),
          ),
        );
      },
    );
  }

  List<Widget> _getFilterWidgets(dynamic filters) {
    List<Widget> children = [];

    for (var i = 0; i < filters.length; i++) {
      dynamic filter = filters[i];
      dynamic choices = filter['choices'];

      for (var j = 0; j < choices.length; j++) {
        dynamic choice = choices[i];
        children.add(CheckboxStatefulWidget(
            label: choice['label']));
      }

      Widget divider = Divider();
      children.add(divider);
    }

    return children;
  }
}

这里是checkbox.dart

import 'package:flutter/material.dart';


class CheckboxStatefulWidget extends StatefulWidget {
  final String label;

  CheckboxStatefulWidget({Key key, this.label}) : super(key: key);

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

class _CheckboxStatefulWidgetState extends State<CheckboxStatefulWidget> {

  bool checkValue;

  @override
  Widget build(BuildContext context) {

    print("checkValue: $checkValue");
    print(checkValue == true ?? false);

    return CheckboxListTile(
        title: Text(this.widget.label),
        value: checkValue == true ?? false,
        onChanged: (bool newValue) {
          setState(() {
            checkValue = newValue;
          });
        });
  }
}

我想你可以试试这个解决方案:

  • 定义一个变量来存储当前的过滤器选项。
  • 当用户提交选项过滤器时 -> 让该过滤器弹出。
  • 注意:模态框会在你2号展示的时候重新创建。因此,您需要将该选项弹出到父小部件以进行存储。
      FilterModel currentFilterOptions;
    
      Future<FilterModel> showFilterModal(context, FilterModel filters) {
        //Show modal 
      }

    ...
    showFilterModal(context, currentFilterOptions).then((value) {
      currentFilterOptions = value;
      //DO STH
    });