Flutter中Material TextFormField被键盘遮挡问题求助
Flutter登录页键盘遮挡输入框的解决方案
问题根源
登录页布局存在两处关键缺陷:
- Scaffold的body使用了带
MainAxisAlignment.spaceBetween的Column,固定了内容垂直位置,导致滚动组件无法动态调整布局 - 外层嵌套的Stack未正确处理键盘Insets,抵消了
resizeToAvoidBottomInset的作用
修复步骤
- 用
SingleChildScrollView包裹Scaffold body内所有内容,确保键盘弹出时内容可滚动 - 移除Column的
mainAxisAlignment: MainAxisAlignment.spaceBetween,改用MainAxisAlignment.start,通过Spacer维持原垂直间距 - 为
SingleChildScrollView添加适配键盘高度的底部内边距:padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom) - 保持Scaffold的
resizeToAvoidBottomInset: true启用状态
修改后的登录页核心代码
@override Widget build(BuildContext parentContext) { final bool loginError = ref.watch(loginErrorProvider); return Container( decoration: const BoxDecoration(color: Colors.white), child: Stack( children: [ Container( decoration: BoxDecoration(color: Theme.of(context).primaryColor), child: Image.asset("assets/backgrounds/bg5.png", height: MediaQuery.of(context).size.height / 2, width: MediaQuery.of(context).size.width, fit: BoxFit.cover), ), CustomPaint( painter: _WaveCustomPaint(backgroundColor: Colors.white), size: Size.infinite, ), WillPopScope( onWillPop: () async => false, child: Scaffold( resizeToAvoidBottomInset: true, appBar: AppBar( automaticallyImplyLeading: false, backgroundColor: Colors.transparent, ), backgroundColor: Colors.transparent, body: SingleChildScrollView( padding: EdgeInsets.only( left: 22, right: 22, top: 70, bottom: MediaQuery.of(context).viewInsets.bottom + 22, ), child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.stretch, children: <Widget>[ Image.asset("assets/logo/logo.png", height: 70), const Spacer(flex: 2), Column( children: [ SzInput( ctrl: _nameAndSurnameController, placeholder: "Inserisci nome", label: "Inserisci nome e cognome", ), const SizedBox(height: 20), SzInput( ctrl: _pnrController, placeholder: "Inserisci PNR", label: "Codice prenotazione", onInfoAction: onInfoPnr, ), const SizedBox(height: 24), if (loginError == true) Text( "I dati inseriti risultano errati o inesistenti", textAlign: TextAlign.center, style: TextStyle( color: HexColor("#FF0000"), fontSize: 16, fontWeight: FontWeight.bold), ), if (loginError == true) const SizedBox(height: 24), LoginButton( onAction: onLoginButtonPressed, ) ], ), const Spacer(flex: 3), const SizedBox(height: 100), ], ), ), )), ], ), ); }
额外说明
Spacer的flex值可根据实际布局需求调整,保证非键盘状态下页面与原设计一致MediaQuery.of(context).viewInsets.bottom会自动获取键盘高度,确保输入框不被遮挡- 无需修改SzInput组件代码,保持原有逻辑即可
内容的提问来源于stack exchange,提问作者Pasquale De Lucia
相关产品推荐
相关产品推荐

