Flutter搜索系统点击空白区域搜索结果消失问题排查
问题原因与修复方案
错误原因
FocusScope上下文错误
你把GestureDetector放在了MaterialApp外面,但MaterialApp会创建独立的FocusScope上下文。这导致你调用FocusScope.of(context)拿到的是外部的FocusScope,无法控制内部TextField的焦点状态。点击空白区域时的unfocus()操作完全无效,反而可能触发意外的状态变更。搜索结果意外重置
点击空白后搜索结果消失,本质是items被重置成了空的pressures列表。大概率是错误的焦点处理导致TextField内容被清空,触发了onChanged的空值逻辑——如果此时pressures在别处被意外清空,就会出现列表为空的情况。
修复步骤
- 调整GestureDetector位置
把GestureDetector移到Scaffold的body内部,这样就能正确获取MaterialApp内部的FocusScope,点击空白区域时可以正常收起键盘,不会触发意外逻辑:
return MaterialApp( debugShowCheckedModeBanner: false, home: Obx( () => Scaffold( resizeToAvoidBottomInset: false, backgroundColor: const Color.fromARGB(255, 15, 15, 15), appBar: AppBar( elevation: 0, toolbarHeight: 90, backgroundColor: Colors.transparent, title: TextField( controller: findPressureController, keyboardType: TextInputType.text, textInputAction: TextInputAction.done, onChanged: (value) { List newList = []; if (value.isNotEmpty) { for (var element in pressures) { if (element.pressure.contains(value) || element.date.toString().contains(value)) { newList.add(element); } } items.value = newList; } else { items.value = pressures; } }, decoration: InputDecoration( hintText: 'Search pressure or date...', hintStyle: GoogleFonts.roboto( color: Colors.white.withOpacity(0.5), fontSize: 20, fontWeight: FontWeight.w700), enabledBorder: OutlineInputBorder( borderRadius: const BorderRadius.all(Radius.circular(15.0)), borderSide: BorderSide( width: 2.0, color: const Color.fromARGB(255, 99, 99, 99) .withOpacity(0.4))), focusedBorder: const OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(15.0)), borderSide: BorderSide( width: 2.0, color: Color.fromARGB(255, 99, 99, 99)))), style: GoogleFonts.roboto( color: Colors.white.withOpacity(0.7), fontSize: 20, fontWeight: FontWeight.w700), )), body: GestureDetector( onTap: () { FocusScopeNode currentFocus = FocusScope.of(context); if (!currentFocus.hasPrimaryFocus) { currentFocus.unfocus(); } }, child: Padding( padding: const EdgeInsets.only(bottom: 15.0), child: ListView.separated( itemCount: items.length, itemBuilder: (context, index) { return pressureItem(index); }, separatorBuilder: (context, index) => const SizedBox(height: 15.0), ), ), ), ), ), );
确保原始数据源稳定
检查pressures列表是否在其他逻辑中被意外清空或修改,确保它始终保存完整的原始数据。优化搜索触发逻辑(可选)
给TextField添加onEditingComplete回调,让搜索逻辑只在用户完成输入时触发,避免焦点变化导致的意外重置:
onEditingComplete: () { String value = findPressureController.text; List newList = []; if (value.isNotEmpty) { for (var element in pressures) { if (element.pressure.contains(value) || element.date.toString().contains(value)) { newList.add(element); } } items.value = newList; } else { items.value = pressures; } FocusScope.of(context).unfocus(); }
内容的提问来源于stack exchange,提问作者Alexandr
相关产品推荐
相关产品推荐

