【问题标题】:How to refresh BottomSheet display with updated state in Flutter?如何在 Flutter 中使用更新状态刷新 BottomSheet 显示?
【发布时间】:2021-10-25 15:16:48
【问题描述】:

我有一个有状态的小部件,其中有一个名为过滤器的列表字段: 我允许用户单击一个按钮来显示 BottomSheet,其中我使用“过滤器”小部件并将过滤器数组作为参数传递。

我现在想要的是能够更改过滤器列表,例如调用 removeFilter 方法并在 BottomSheet 中更新?

在下面的代码中,当我调用 removeFilter 时,它使用新的过滤器数组正确更新了过滤器状态,但底部的模态表没有更新。

如何让状态反映在 BottomSheet 中(无需在每次更改时重新构建底部表)?

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

【问题讨论】:

    标签: flutter


    【解决方案1】:

    您可以使用 ScaffoldState 中的 showBottomSheet。

    这将显示bottomSheet并返回一个控制器PersistentBottomSheetController。使用此控制器,您可以调用 controller.SetState((){}),这将重新渲染 bottomSheet

    例如

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

    【讨论】:

    • 尝试添加,但 showModalBottomSheet 行给出错误:无法无条件调用方法“showModalBottomSheet”,因为接收器可以为“null”。尝试使调用有条件(使用'?.')或向目标添加空检查('!')。
    • 我错过了为 Scaffold 分配密钥,所以它从这个角度工作。但是,ShowBottomSheet 与 ShowBottomModalSheet 不同,因为 ShowBottomModalSheet 允许参数 isScrollControlled,当用户单击文本表单字段时,我需要获得正确的行为。 ShowBottomSheet 没有这个参数,当点击一个字段时,它会占据整个屏幕。有什么解决办法吗?
    • 你可以调用 controller.SetState((){}) 来更新bottomSheet
    猜你喜欢
    • 2022-07-23
    • 1970-01-01
    • 2019-02-24
    • 2020-11-28
    • 1970-01-01
    • 2021-09-26
    • 2022-08-21
    • 2018-10-16
    • 1970-01-01
    相关资源
    最近更新 更多