Home > Mobile >  Flutter can't preserve stateful state when exit showModalBottomSheet and show showModalBottomSh
Flutter can't preserve stateful state when exit showModalBottomSheet and show showModalBottomSh

Time:12-13

So I have the following code to showModalBottomSheet, and display filters/checkboxes on the page. If I exit the modal and show the showModalBottomSheet again, then I don't see the checkbox values got preserved.

It seems the 2nd time I show the modal, the build() from _CheckboxStatefulWidgetState was called again, and then default the checkValue to null.

Here is 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;
  }
}

Here is 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;
          });
        });
  }
}

CodePudding user response:

I think you can try with this solution:

  • Define a variable to store currently filter options.
  • When user submit options filter -> let pop that filter.
  • note: Modal will create again when you show on 2nd. So you need pop that option to parent widget to store.
      FilterModel currentFilterOptions;
    
      Future<FilterModel> showFilterModal(context, FilterModel filters) {
        //Show modal 
      }

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