You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

键盘打开时关闭EndDrawer抛出Widget已卸载异常求助

问题:关闭打开键盘的EndDrawer时触发组件已卸载异常

当键盘处于打开状态时关闭EndDrawer会触发如下断言异常,键盘未聚焦时无此问题。抽屉内包含SearchField组件,本不应出现该错误。

异常信息

======== Exception caught by widgets library =======================================================
The following assertion was thrown building StreamBuilder<List<SearchFieldListItem<dynamic>?>?>(dirty, state: _StreamBuilderBaseState<List<SearchFieldListItem<dynamic>?>?, AsyncSnapshot<List<SearchFieldListItem<dynamic>?>?>>#75ea8):
This widget has been unmounted, so the State no longer has a context (and should be considered defunct). 

相关代码

appBar: AppBar(title: Text('XYZ')),
endDrawer: Drawer(
  child: ListView(
    children: [
      Padding(
        padding: EdgeInsets.all(10),
        child: SizedBox(
          child: const DrawerHeader(
            child: Text('Filter'),
          ),
        ),
      ),
      Padding(
        padding: EdgeInsets.all(10),
        child: Container(
          child: SearchField<Model>(
            onSuggestionTap: (buyerValue) {},
          ),
        ),
      ),
    ],
  ),
),
body: Container(),

解决方案

方法1:主动取消SearchField的焦点

通过给SearchField绑定FocusNode,在抽屉关闭时主动取消焦点,避免键盘未收起导致组件状态异常更新:

  1. 定义FocusNode:
    final FocusNode _searchFocusNode = FocusNode();
    
  2. 给SearchField绑定FocusNode:
    SearchField<Model>(
      focusNode: _searchFocusNode,
      onSuggestionTap: (buyerValue) {},
    ),
    
  3. 在Scaffold中监听抽屉状态,关闭时取消焦点:
    Scaffold(
      // ...其他配置项
      onEndDrawerChanged: (isOpen) {
        if (!isOpen) {
          _searchFocusNode.unfocus();
        }
      },
      endDrawer: // ...你的抽屉代码
    )
    

方法2:在StreamBuilder中判断组件挂载状态

如果可以修改SearchField内部的StreamBuilder逻辑,在构建UI前先判断组件是否仍处于挂载状态,避免卸载后触发状态更新:

StreamBuilder<List<SearchFieldListItem<dynamic>?>?>(
  stream: // 原数据流配置
  builder: (context, snapshot) {
    // 先校验组件挂载状态
    if (!context.mounted) return const SizedBox.shrink();
    // 原有的UI构建逻辑
  },
)

方法3:关闭抽屉前强制隐藏键盘

在触发抽屉关闭的操作前,先主动隐藏键盘,确保组件状态稳定后再关闭抽屉:

// 示例:关闭按钮的点击事件
onPressed: () {
  FocusManager.instance.primaryFocus?.unfocus();
  Navigator.of(context).pop();
}

内容的提问来源于stack exchange,提问作者Neev Shah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 13:45:29