Flutter中TextFormField点击后键盘不弹出问题求助
Flutter TextFormField点击后键盘无法弹出的问题
点击TextFormField准备输入时,键盘无法弹出。已尝试以下方案均无效:
- 在无状态组件与有状态组件间相互转换
- 在导入后、Cubit文件、共享文件中声明全局TextEditingController
- 不使用Form组件
- 移除onFieldSubmitted属性
- 执行
flutter run --release命令但终端无输出 - 检查Google Play控制台的崩溃日志
搜索页面代码
import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class SearchScreen extends StatefulWidget { const SearchScreen({Key? key}) : super(key: key); @override State<SearchScreen> createState() => _SearchScreenState(); } class _SearchScreenState extends State<SearchScreen> { @override Widget build(BuildContext context) { var size = MediaQuery.of(context).size; var width = size.width; return BlocConsumer<HomeCubit, HomeStates>( listener: (context, state) {}, builder: (context, state) { var cubit = HomeCubit.get(context); return Directionality( textDirection: TextDirection.rtl, child: Scaffold( body: SingleChildScrollView( child: Column( children: [ Padding( padding: const EdgeInsets.symmetric(horizontal: 10.0), child: Row( children: [ // which zone text SizedBox( width: width * .30, child: FittedBox(child: Text('اختر المنطقة',style: TextStyle(fontSize: 24,fontWeight:FontWeight.normal)))) const SizedBox(width: 25.0), Expanded( child: Center( child: DropdownButton( alignment: Alignment.center, value: cubit.zonePopupValue, hint: const Text('كل المناطق', textAlign: TextAlign.center), style: TextStyle( color: HexColor('#ECB365'), fontSize: 24, fontWeight: FontWeight.normal, ), items: cubit.list, onChanged: (value) => cubit.changePopupZoneValue(int.parse(value.toString())), ), ), ), ], ) ), Padding( padding: const EdgeInsets.symmetric(horizontal: 10), child: TextFormField( textInputAction: TextInputAction.search, onFieldSubmitted: (_) async => cubit.search(), controller: cubit.searchController, keyboardType: TextInputType.text, maxLines: 1, maxLength: 100, textAlign: TextAlign.right, textDirection: TextDirection.rtl, decoration: InputDecoration( contentPadding: const EdgeInsets.only(right: 20, left: 10), labelText: "إبحث", alignLabelWithHint: true, labelStyle: TextStyle( color: HexColor('#ECB365'), fontSize: 24, fontWeight: FontWeight.normal, ), suffixIcon: cubit.isLoadingAuth? CircularProgressIndicator(color: HexColor('#ECB365')): IconButton( onPressed: () => cubit.search(), icon: Icon(Icons.search,color: HexColor('#ECB365')), iconSize: 35, color: HexColor('#081C31'), ), border: OutlineInputBorder(borderSide:BorderSide(color: HexColor('#ECB365'))), focusedBorder: OutlineInputBorder(borderSide: BorderSide(color: HexColor('#ECB365'))), enabledBorder: OutlineInputBorder(borderSide:BorderSide(color: HexColor('#ECB365'))), fillColor: HexColor('#ECB365') ), ) ), Container( margin: const EdgeInsets.only(left: 10.0, right: 20.0), child: const Divider(color: Colors.black,height: 36) ), cubit.responseBodySearch == null ? const Center(child: Text("أبدأ البحث")) : cubit.responseBodySearch.isEmpty ? const Center(child: Text("غير متوفر حاليا")) : ListView.builder( physics: const NeverScrollableScrollPhysics(), shrinkWrap: true, itemCount: cubit.responseBodySearch!.length, itemBuilder: (context, index) => buildSearchItem(cubit, context, index) ) ], ), ), ) ); } ); } }
HomeCubit代码
class HomeCubit extends Cubit<HomeStates> { HomeCubit() : super(HomeInitState()); static HomeCubit get(context) => BlocProvider.of(context); String api = 'https://hadayekhof.com/dalel/api/'; var searchController = TextEditingController(); int? zonePopupValue; void changePopupZoneValue(int value) { zonePopupValue = value; getCategoriesData(zoneIds[value].toString()); emit(HomeChangePopupButtonState()); } var responseBodySearch; Future search() async { emit(HomeSearchLoadingState()); responseBodySubCategories = null; var data = { 'zone_id': zonePopupValue == null ? '' : zoneIds[zonePopupValue!].toString(), // 'parent_cat': categoryPopupValue == null ? '' : categoryIds[categoryPopupValue!].toString(), 'term': searchController.text.toString() }; var uri = Uri.parse('${api}stores/searchStores'); var header = {'Authorization': 'Bearer $ciphertext'}; if (searchController.text == '') { Fluttertoast.showToast(msg: 'من فضلك اكتب شئ'); } else { await http.post(uri, body: data, headers:header ).then((value) async { responseBodySearch = await jsonDecode(value.body); if (value.body.toString().contains('[') == false) { responseBodySearch = null; Fluttertoast.showToast(msg: 'no stores found'); } emit(HomeSearchSuccessState()); }).catchError((error) { debugPrint("search error is : $error"); emit(HomeSearchErrorState()); }); } } }
排查与解决方案
调整TextEditingController初始化逻辑
Cubit中直接初始化searchController可能导致生命周期不匹配,建议在Cubit构造函数内初始化,或者在SearchScreen的initState中创建控制器并与Cubit关联,避免全局控制器绑定异常。手动控制焦点获取
给TextFormField添加FocusNode,强制请求焦点:final FocusNode _searchFocusNode = FocusNode(); @override void dispose() { _searchFocusNode.dispose(); super.dispose(); } // 绑定到TextFormField TextFormField( focusNode: _searchFocusNode, onTap: () { FocusScope.of(context).requestFocus(_searchFocusNode); }, // 其他属性... )检查Scaffold布局属性
确保Scaffold未设置resizeToAvoidBottomInset: false,该属性会阻止页面适配键盘,可能间接导致键盘无法弹出。优化Bloc重建范围
Bloc状态更新会触发builder重建,若重建频繁可能导致TextFormField失焦。将TextFormField部分提取为独立StatefulWidget,或用const关键字减少不必要的组件重建。测试极简场景
创建仅包含TextFormField和控制器的测试页面,验证键盘是否正常弹出。若正常,再逐步添加Bloc、DropdownButton等元素,定位冲突点。检查设备输入法设置
确认设备/模拟器的输入法未被禁用,比如iOS模拟器需关闭硬件键盘,Android设备需确保默认输入法正常工作。
内容的提问来源于stack exchange,提问作者Saayeed M Daawoud
相关产品推荐
相关产品推荐

