Flutter TextFormField错误文本导致高度增加引发底部溢出如何解决?
问题原因
你的布局溢出核心是ConstrainedBox设置了minHeight: constraints.maxHeight,同时搭配IntrinsicHeight强制Column高度撑满父容器可用高度,当表单验证失败弹出错误提示时,表单项总高度增加,超过了父容器限制的最大高度,就会出现底部溢出。
修复方案
方案1:按钮跟随表单内容滚动
移除高度锁死的相关配置,让Column自适应内容高度,由外层SingleChildScrollView处理滚动即可:
Form _buildForm(BuildContext context, BoxConstraints constraints) { print(constraints); return Form( key: _form, child: SingleChildScrollView( physics: const AlwaysScrollableScrollPhysics(), child: Container( padding: const EdgeInsets.only(bottom: 20), width: constraints.maxWidth, child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ Padding( padding: const EdgeInsets.only(top: 48, bottom: 32), child: Text( 'Sign Up', style: AppTheme.theme.textTheme.headline3 .copyWith(color: AppColors.black), ), ), LabeledTextField( margin: EdgeInsets.only(bottom: 16), fieldName: 'Email', decoration: InputDecoration(hintText: 'example@mail.com'), textInputAction: TextInputAction.next, onFieldSubmitted: (_) { FocusScope.of(context).requestFocus(_userNameFocusNode); }, onSaved: (val) => _authData["login"] = val, validator: FormValidators.emailValidator, autovalidateMode: AutovalidateMode.onUserInteraction, ), LabeledTextField( margin: EdgeInsets.only(bottom: 16), fieldName: 'User Name', decoration: InputDecoration(hintText: 'alexexample...'), textInputAction: TextInputAction.next, onFieldSubmitted: (_) { FocusScope.of(context).requestFocus(_passwordFocusNode); }, onSaved: (val) => _authData["username"] = val, validator: FormValidators.isRequiredValidator, autovalidateMode: AutovalidateMode.onUserInteraction, ), LabeledTextField( margin: EdgeInsets.only(bottom: 32), fieldName: 'Password', focusNode: _passwordFocusNode, obscureText: true, decoration: InputDecoration(hintText: 'Type in...'), onSaved: (val) => _authData["password"] = val, validator: FormValidators.passwordValidator, autovalidateMode: AutovalidateMode.onUserInteraction, ), AuthButtons( mode: AuthMode.signup, saveForm: _saveForm, ), ], ), ), ), ); }
方案2:按钮固定在屏幕底部
如果需要按钮始终显示在可视区域底部,直接用Scaffold自带的persistentFooterButtons属性承载按钮,系统会自动处理键盘弹出、内容变化时的按钮位置适配:
@override Widget build(BuildContext context) { return Scaffold( appBar: CustomAppBar( preferredSize: Size.fromHeight(64), title: 'title', ), persistentFooterButtons: [ Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), child: AuthButtons( mode: AuthMode.signup, saveForm: _saveForm, ), ) ], body: Padding( padding: const EdgeInsets.only(left: 16, right: 16, bottom: 80), child: LayoutBuilder( builder: (context, constraints) => _buildForm(context, constraints), ), ), ); }
使用该方案需要把_buildForm中Column里的Spacer和AuthButtons组件移除。
额外注意
不要给LabeledTextField设置固定高度,错误提示会增加组件总高度,固定高度会挤压输入框显示,让组件自适应内容高度即可。
内容的提问来源于stack exchange,提问作者Zimme
相关产品推荐
相关产品推荐

