Flutter:TextFormField点击后键盘弹出即消失,添加配置无效求助
问题描述
我的Flutter应用里,TextFormField组件出了问题:点击后键盘弹出来立刻就关闭,控制台输出以下日志:
D/InputConnectionAdaptor( 7900): The input method toggled cursor monitoring on
W/OnBackInvokedCallback( 7900): OnBackInvokedCallback is not enabled for the application.
Set 'android:enableOnBackInvokedCallback="true"' in the application manifest.
D/InputConnectionAdaptor( 7900): The input method toggled cursor monitoring off
我已经在AndroidManifest.xml里加了提示的配置,但问题还是没解决。
下面是我的SearchBox组件代码:
class SearchBox extends StatelessWidget { const SearchBox({ super.key, required this.controller, }); final TextEditingController controller; @override Widget build(BuildContext context) { return Padding( padding: EdgeInsets.symmetric( horizontal: Dimensions.widthPercentage(context, 10), vertical: Dimensions.heightPercentage(context, 2)), child: Container( height: Dimensions.heightPercentage(context, 8), decoration: BoxDecoration( color: AppColors.whiteColor, borderRadius: BorderRadius.circular( Dimensions.radius(context, 2.55), ), ), child: TextFormField( controller: controller, textInputAction: TextInputAction.none, decoration: InputDecoration( hintText: 'What do you like to eat today?'.tr, hintStyle: TextStyle( fontSize: Dimensions.fontSize(context, 3.75), color: AppColors.hintSmallText, fontFamily: 'ReadexPro', ), border: InputBorder.none, contentPadding: EdgeInsets.symmetric( horizontal: Dimensions.widthPercentage(context, 10), vertical: Dimensions.heightPercentage(context, 3), ), suffixIcon: Padding( padding: EdgeInsets.only( right: Dimensions.widthPercentage( context, 3)), // Adjust as needed child: const Icon( Icons.search, color: Colors.black, ), ), ), ), ), ); } }
更新:以下是HomePage中调用SearchBox的代码:
class HomePage extends StatelessWidget { const HomePage({super.key}); @override Widget build(BuildContext context) { GlobalKey<ScaffoldState> homeKey = GlobalKey<ScaffoldState>(); return Obx( () { final controller = Get.find<HomePageController>(); return SafeArea( child: Material( child: Stack( alignment: Alignment.bottomCenter, children: [ Scaffold( backgroundColor: AppColors.background, key: homeKey, body: ListView( children: [ BigImage( controller: controller.pageController, length: controller.images.length, listItem: controller.images, hasText: false, isHomePage: true, ), SearchBox( controller: controller.searchController, ), ], ), ), Visibility( visible: !isDrawerOpen.value, child: BNBWidget( scaffoldKey: homeKey, cartStatus: controller.items.isNotEmpty, onHomeTap: () {}, ), ), ], ), ), ); }, ); } }
解决方案
1. 修复GlobalKey的定义位置
把HomePage里的GlobalKey<ScaffoldState>移到类的成员变量位置,不要在build方法里创建:
class HomePage extends StatelessWidget { const HomePage({super.key}); // 移到这里作为类成员 final GlobalKey<ScaffoldState> homeKey = GlobalKey<ScaffoldState>(); @override Widget build(BuildContext context) { // 删掉build里的homeKey定义 return Obx( () { final controller = Get.find<HomePageController>(); return SafeArea( child: Material( child: Stack( alignment: Alignment.bottomCenter, children: [ Scaffold( backgroundColor: AppColors.background, key: homeKey, // 其余代码不变 ), // 其余代码不变 ], ), ), ); }, ); } }
2. 确认TextEditingController的初始化逻辑
确保HomePageController里的searchController是在控制器初始化时创建,并且在销毁时释放:
class HomePageController extends GetxController { final TextEditingController searchController = TextEditingController(); // 其余业务逻辑... @override void onClose() { searchController.dispose(); super.onClose(); } }
3. 移除多余的Material嵌套
Scaffold本身已经包含Material组件,外层的嵌套会导致上下文冲突,直接删掉:
return SafeArea( // 去掉外层的Material child: Stack( alignment: Alignment.bottomCenter, children: [ Scaffold( backgroundColor: AppColors.background, key: homeKey, body: ListView( // 其余代码不变 ), ), // 其余代码不变 ], ), );
4. 检查isDrawerOpen的状态稳定性
确保isDrawerOpen是RxBool类型的可观察状态,避免频繁触发组件重建:
// 比如在全局或控制器里定义 final RxBool isDrawerOpen = false.obs;
原因说明
GlobalKey在build方法内创建会导致每次组件重建都生成新Key,Scaffold状态被重置,间接让TextFormField丢失焦点,键盘弹出后立刻关闭。- 不稳定的
TextEditingController或频繁的组件重建会干扰输入框的焦点生命周期。 - 多余的
Material嵌套会造成上下文混乱,影响输入框和键盘的交互逻辑。
内容的提问来源于stack exchange,提问作者Muhammad Qazmouz

