Flutter中Row内TextField与其他组件的Web端垂直对齐问题
问题:Flutter Web端TextField垂直对齐失效,移动端正常
这段Flutter代码实现了带加减按钮的数字输入组件,在iOS和Android端运行时,输入框内的文字能和左右按钮垂直居中对齐,但在Web浏览器中,输入框文字无法实现垂直居中。
原代码
return LayoutBuilder( builder: (context, constraints) { double parentHeight = constraints.maxHeight; return Row( mainAxisAlignment: MainAxisAlignment.spaceAround, crossAxisAlignment: CrossAxisAlignment.center, children: [ InkWell( borderRadius: BorderRadius.circular(5), onTap: () { if (int.parse(controller.text) > 0) { updateValue((int.parse(controller.text) - 1)); } }, child: Container( height: parentHeight, width: parentHeight, decoration: BoxDecoration( color: const Color(0xFFcc0000), borderRadius: BorderRadius.circular(5), ), padding: const EdgeInsets.all(2), child: Center( child: Icon( Icons.remove, size: parentHeight * 0.8, color: Colors.white, ), ), ), ), SizedBox( width: parentHeight * 2, height: parentHeight, child: Focus( onFocusChange: (hasFocus) { if (!hasFocus) { if (controller.text.isEmpty) { setState(() { controller.text = '0'; updateValue(0); }); } else { updateValue(int.parse(controller.text)); } } }, child: TextFormField( expands: true, minLines: null, maxLines: null, controller: controller, enableInteractiveSelection: false, textInputAction: TextInputAction.done, textAlign: TextAlign.center, style: TextStyle( fontWeight: FontWeight.bold, fontSize: parentHeight * 0.6, ), keyboardType: kIsWeb ? const TextInputType.numberWithOptions( signed: false, decimal: false, ) : Platform.isIOS ? const TextInputType.numberWithOptions( signed: true, decimal: true, ) : const TextInputType.numberWithOptions( signed: false, decimal: false, ), cursorColor: const Color(0xffcc0000), maxLength: 3, decoration: const InputDecoration( counterText: "", border: InputBorder.none, contentPadding: EdgeInsets.zero, ), inputFormatters: <TextInputFormatter>[ FilteringTextInputFormatter.digitsOnly, FilteringTextInputFormatter.allow(RegExp(r'[0-9]')), ], autocorrect: false, textCapitalization: TextCapitalization.none, onChanged: (value) { controller.text = value; }, onFieldSubmitted: (value) { if (controller.text.isEmpty) { setState(() { controller.text = '0'; updateValue(0); }); } else { updateValue(int.parse(controller.text)); } }, onTap: () { if (controller.text == '0') { controller.text = ''; } }, onEditingComplete: () { if (controller.text.isEmpty) { setState(() { controller.text = '0'; updateValue(0); }); } else { updateValue(int.parse(controller.text)); } }, ), ), ), InkWell( borderRadius: BorderRadius.circular(5), onTap: () { updateValue((int.parse(controller.text) + 1)); }, child: Container( height: parentHeight, width: parentHeight, decoration: BoxDecoration( color: const Color(0xFFcc0000), borderRadius: BorderRadius.circular(5), ), padding: const EdgeInsets.all(2), child: Center( child: Icon( Icons.add, size: parentHeight * 0.8, color: Colors.white, ), ), ), ), ], ); }, );
问题原因
你猜测的expands: true属性在Web端的兼容性问题是核心原因。Flutter Web的TextField在启用expands: true时,内部文本布局逻辑与移动端存在差异,无法正确响应垂直居中设置;同时contentPadding: EdgeInsets.zero会进一步放大问题,Web端原生输入框的基线对齐逻辑会导致文字偏移。
解决方案
移除expands相关属性,改用textAlignVertical强制垂直居中,同时保留父容器的尺寸约束:
修改后的TextField关键代码
TextFormField( // 移除expands、minLines、maxLines属性 controller: controller, enableInteractiveSelection: false, textInputAction: TextInputAction.done, textAlign: TextAlign.center, // 添加强制垂直居中配置 textAlignVertical: TextAlignVertical.center, style: TextStyle( fontWeight: FontWeight.bold, fontSize: parentHeight * 0.6, ), keyboardType: kIsWeb ? const TextInputType.numberWithOptions( signed: false, decimal: false, ) : Platform.isIOS ? const TextInputType.numberWithOptions( signed: true, decimal: true, ) : const TextInputType.numberWithOptions( signed: false, decimal: false, ), cursorColor: const Color(0xffcc0000), maxLength: 3, decoration: const InputDecoration( counterText: "", border: InputBorder.none, contentPadding: EdgeInsets.zero, ), // 其余属性保持不变 inputFormatters: <TextInputFormatter>[ FilteringTextInputFormatter.digitsOnly, FilteringTextInputFormatter.allow(RegExp(r'[0-9]')), ], autocorrect: false, textCapitalization: TextCapitalization.none, onChanged: (value) { controller.text = value; }, onFieldSubmitted: (value) { if (controller.text.isEmpty) { setState(() { controller.text = '0'; updateValue(0); }); } else { updateValue(int.parse(controller.text)); } }, onTap: () { if (controller.text == '0') { controller.text = ''; } }, onEditingComplete: () { if (controller.text.isEmpty) { setState(() { controller.text = '0'; updateValue(0); }); } else { updateValue(int.parse(controller.text)); } }, )
完整修改说明
- 删除
expands: true、minLines: null、maxLines: null,避免Web端布局冲突 - 添加
textAlignVertical: TextAlignVertical.center,直接强制文本在输入框内垂直居中 - 保留父容器SizedBox的固定宽高,确保输入框尺寸约束稳定
修改后,组件在移动端和Web端都能实现文字垂直居中对齐的效果。
内容的提问来源于stack exchange,提问作者Abdullah Saeed
相关产品推荐
相关产品推荐

