Flutter中TextFormField与DropdownButton下划线未对齐问题
问题描述
将TextFormField和DropdownButton组件置于Row布局内时,二者的下划线不在同一水平线上,效果如下:
相关实现代码:
Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.end, children: [ SizedBox( width: HDW().fullWidth(context: context, width: 0.35), height: HDW().fullHeight(context: context, height: 0.08), child: TextFormField( controller: sectionTextEditingController, onChanged: (n) { homeController.setSectionNo(n); }, keyboardType: TextInputType.number, ), ), SizedBox( width: HDW().fullWidth(context: context, width: 0.35), height: HDW().fullHeight(context: context, height: 0.08), child: DropdownButton<String?>( items: homeController.sections .map((e) => DropdownMenuItem<String?>( value: e, child: Text( e,textAlign: TextAlign.start,style: TextStyle(fontFamily: font),), ),) .toList(), value: homeController.selectedLetter.isNotEmpty ? homeController.selectedLetter : null, onChanged: (value) { homeController.setSectionLetter(value!); }, hint: Text( 'تحديد', style: TextStyle(fontFamily: font), ), isExpanded: true, icon: const Icon(Icons.keyboard_arrow_down), ), ), ], )
补充说明:fullHeight方法定义:
double fullHeight({ required BuildContext context, double height = 1, }) => height * MediaQuery.of(context).size.height;
解决方案
造成下划线不对齐的核心原因是TextFormField和DropdownButton的默认内边距、基线位置不一致,可通过以下方式修复:
方法1:用InputDecorator统一包裹DropdownButton
将DropdownButton放入InputDecorator中,使其拥有与TextFormField一致的下划线样式和布局逻辑:
Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.end, children: [ SizedBox( width: HDW().fullWidth(context: context, width: 0.35), height: HDW().fullHeight(context: context, height: 0.08), child: TextFormField( controller: sectionTextEditingController, onChanged: (n) { homeController.setSectionNo(n); }, keyboardType: TextInputType.number, ), ), SizedBox( width: HDW().fullWidth(context: context, width: 0.35), height: HDW().fullHeight(context: context, height: 0.08), child: InputDecorator( decoration: const InputDecoration( border: UnderlineInputBorder(), contentPadding: EdgeInsets.zero, ), child: DropdownButton<String?>( isExpanded: true, underline: const SizedBox(), // 隐藏DropdownButton自带下划线 items: homeController.sections .map((e) => DropdownMenuItem<String?>( value: e, child: Text(e, textAlign: TextAlign.start, style: TextStyle(fontFamily: font)), )) .toList(), value: homeController.selectedLetter.isNotEmpty ? homeController.selectedLetter : null, onChanged: (value) { homeController.setSectionLetter(value!); }, hint: Text( 'تحديد', style: TextStyle(fontFamily: font), ), icon: const Icon(Icons.keyboard_arrow_down), ), ), ), ], )
方法2:基于文本基线对齐
修改Row的对齐方式为基线对齐,让两个组件的文本基线统一,从而带动下划线对齐:
Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.baseline, textBaseline: TextBaseline.alphabetic, children: [ SizedBox( width: HDW().fullWidth(context: context, width: 0.35), height: HDW().fullHeight(context: context, height: 0.08), child: TextFormField( controller: sectionTextEditingController, onChanged: (n) { homeController.setSectionNo(n); }, keyboardType: TextInputType.number, ), ), SizedBox( width: HDW().fullWidth(context: context, width: 0.35), height: HDW().fullHeight(context: context, height: 0.08), child: DropdownButton<String?>( items: homeController.sections .map((e) => DropdownMenuItem<String?>( value: e, child: Text(e, textAlign: TextAlign.start, style: TextStyle(fontFamily: font)), )) .toList(), value: homeController.selectedLetter.isNotEmpty ? homeController.selectedLetter : null, onChanged: (value) { homeController.setSectionLetter(value!); }, hint: Text( 'تحديد', style: TextStyle(fontFamily: font), ), isExpanded: true, icon: const Icon(Icons.keyboard_arrow_down), ), ), ], )
方法3:自定义下划线偏移
通过调整两个组件的内边距和下划线位置,让下划线处于同一水平线:
Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.end, children: [ SizedBox( width: HDW().fullWidth(context: context, width: 0.35), height: HDW().fullHeight(context: context, height: 0.08), child: TextFormField( controller: sectionTextEditingController, onChanged: (n) { homeController.setSectionNo(n); }, keyboardType: TextInputType.number, decoration: const InputDecoration( contentPadding: EdgeInsets.only(bottom: 8), ), ), ), SizedBox( width: HDW().fullWidth(context: context, width: 0.35), height: HDW().fullHeight(context: context, height: 0.08), child: DropdownButton<String?>( items: homeController.sections .map((e) => DropdownMenuItem<String?>( value: e, child: Text(e, textAlign: TextAlign.start, style: TextStyle(fontFamily: font)), )) .toList(), value: homeController.selectedLetter.isNotEmpty ? homeController.selectedLetter : null, onChanged: (value) { homeController.setSectionLetter(value!); }, hint: Text( 'تحديد', style: TextStyle(fontFamily: font), ), isExpanded: true, icon: const Icon(Icons.keyboard_arrow_down), underline: Container( height: 1, margin: const EdgeInsets.only(bottom: 8), color: Colors.grey, ), ), ), ], )
内容的提问来源于stack exchange,提问作者Husamuldeen Abdlrahman
相关产品推荐
相关产品推荐

