You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中TextFormField与DropdownButton下划线未对齐问题

Flutter中Row内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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 06:05:27