How to refresh BottomSheet display with updated state in Flutter?

Viewed 825

I have a statefull widget in which I have a List field called filters: I allow the user to click a button to show the BottomSheet where I use a "Filters" widget and pass in the filters array as a parameter.

What I want now is to be able to change the filter List, for example calling removeFilter method and have that updated in the BottomSheet?

In the code below, when I call removeFilter, it correctly updates the filters state with the new filter array, but the bottom modal sheet is not updated.

How do I get the state to be reflected in the BottomSheet (without needing to rebuild the bottom sheet with every change)?

  List<dynamic> filters = [];


  void removeFilter(String field) {
    List<dynamic> updatedFilters =
        filters.where((element) => element['field'] != field).toList();

    this.setState(() {
      filters = updatedFilters;
    });
  }

  void showFiltersScreen(BuildContext context, String field) {

    showModalBottomSheet(
      context: context,
      isScrollControlled: true,
      builder: (context) {
        return  Padding(
          padding:
              EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
          child: Filters(
            blockColor: widget.blockData.color,
            tableinfo: _tableinfo,
            filters: filters,
            removeFilter: this.removeFilter,
            setState: setState,
          ),
        );
  });
  }
1 Answers

You can use the showBottomSheet from the ScaffoldState.

This will show the bottomSheet and return a controller PersistentBottomSheetController. with this controller you can call controller.SetState((){}) which will re-render the bottomSheet

for example

List<dynamic> filters = [];
PersistentBottomSheetController _controller; // <------ Instance variable
final _scaffoldKey = GlobalKey<ScaffoldState>(); // <---- Another instance variable


void removeFilter(String field) {
  List<dynamic> updatedFilters =
      filters.where((element) => element['field'] != field).toList();

  this.setState(() {
    filters = updatedFilters;
  });
 }

void showFiltersScreen(BuildContext context, String field) {

_controller = await _scaffoldKey.currentState.showModalBottomSheet(
  context: context,
  isScrollControlled: true,
  builder: (context) {
    return  Padding(
      padding:
          EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
      child: Filters(
        blockColor: widget.blockData.color,
        tableinfo: _tableinfo,
        filters: filters,
        removeFilter: this.removeFilter,
        setState: setState,
      ),
    );
 });
}
Related