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

Flutter登录UI问题:TextField尺寸不一致、按钮溢出及下划线调整

Flutter登录UI问题解决方案

针对你遇到的三个问题,逐一解决如下:

1. 邮箱与密码TextField尺寸不一致

问题根源:密码TextField使用了suffix属性放置图标,suffix是无约束的自定义Widget,会打破TextField的默认布局规则;而邮箱TextField用的是prefixIcon,属于TextField内置的标准化图标布局。

解决方法:将密码TextField的suffix替换为suffixIcon,它会和prefixIcon保持一致的布局逻辑,自动匹配TextField的高度。

修改后的密码TextField代码片段:

TextField(
  obscureText: _isVisible ? false : true,
  keyboardType: TextInputType.visiblePassword,
  decoration: InputDecoration(
    // 替换suffix为suffixIcon
    suffixIcon: IconButton(
      onPressed: () {
        setState(() {
          _isVisible = !_isVisible;
        });
      },
      icon: Icon(
        _isVisible ? Icons.visibility : Icons.visibility_off,
        color: Colors.grey,
      ),
    ),
    border: OutlineInputBorder(
      borderRadius: BorderRadius.all(
        Radius.circular(10.0),
      ),
      borderSide: BorderSide(
        width: 0,
        style: BorderStyle.none,
      ),
    ),
    filled: true,
    fillColor: Color(0xffe73ded),
    hintText: "Password",
    prefixIcon: Icon(
      Icons.lock_rounded,
      color: Colors.grey,
    ),
  ),
),

2. 登录按钮13像素溢出

问题根源:登录按钮外层嵌套的Container(color: Colors.blue)与ElevatedButton的内边距、样式规则冲突,导致容器宽度超出父布局范围。

解决方法:移除多余的外层Container,直接通过ElevatedButton.styleFrom设置背景色和布局规则,确保按钮占满父容器宽度且无溢出。

修改后的登录按钮代码片段:

ElevatedButton(
  onPressed: () {},
  style: ElevatedButton.styleFrom(
    backgroundColor: Colors.blue, // 显式设置按钮背景色
    shape: RoundedRectangleBorder(
      borderRadius: BorderRadius.circular(28),
    ),
    minimumSize: Size(double.infinity, 0), // 确保按钮占满父容器宽度
    padding: EdgeInsets.symmetric(vertical: 16.0), // 统一设置内边距
  ),
  child: Text(
    'Login',
    style: TextStyle(
      color: Colors.white,
      fontSize: 16.0,
    ),
  ),
),

3. 调整“Forgot your password”文本的下划线高度

问题根源:默认的TextDecoration.underline厚度固定,无法直接调整,需通过TextStyle的专属属性自定义。

解决方法:在TextStyle中添加decorationThickness设置下划线厚度,可选decorationOffset调整下划线的垂直位置。

修改后的“Forgot your password”代码片段:

TextButton(
  onPressed: () {},
  child: Text(
    'Forgot your password',
    style: TextStyle(
      color: Colors.blue,
      decoration: TextDecoration.underline,
      decorationThickness: 2.0, // 自定义下划线厚度,按需修改数值
      decorationOffset: Offset(0, 2), // 可选,调整下划线与文本的垂直距离
    ),
  ),
),

完整修改后的代码

import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';

void main() => runApp(MyApp());    
class MyApp extends StatelessWidget {
  const MyApp({super.key});    
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Navigation Bar',
      theme: ThemeData(
        primaryColor: Color(0xFFC41A3B),           
      ),
      home: MyHomePage(),
    );
  }
}    
class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});
  @override
  State<MyHomePage> createState() => _MyHomePageState();
}    
class _MyHomePageState extends State<MyHomePage> {
  var _isVisible = false;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SingleChildScrollView(
        child: Container(
          constraints: BoxConstraints(
            maxHeight: MediaQuery.of(context).size.height,               
          ),
            decoration: BoxDecoration(
            gradient: LinearGradient(
              colors: const [
                Colors.blue,                    
              ],
              begin: Alignment.topLeft,
              end: Alignment.centerRight,
            ),
          ),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.start,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Expanded(
                flex: 2,
                child: Padding(
                  padding: const EdgeInsets.symmetric(
                    vertical: 36.0,
                    horizontal: 24.0,
                  ),
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.end,
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: const [
                      Text(
                        'Login',
                        style: TextStyle(
                          color: Colors.white,
                          fontSize: 46.0,
                          fontWeight: FontWeight.w800,
                        ),
                      ),
                      SizedBox(
                        height: 10.0,
                      ),
                      Text(
                        'Enter to the butiful world',
                        style: TextStyle(
                          color: Colors.white,
                          fontSize: 22.0,
                          fontWeight: FontWeight.w300,
                        ),
                      ),
                    ],
                  ),
                ),
              ),
              Expanded(
                flex: 2,
                child: Container(
                  width: double.infinity,
                  decoration: BoxDecoration(
                    color: Colors.white,
                    borderRadius: BorderRadius.only(
                      topLeft: Radius.circular(30),
                      topRight: Radius.circular(30),
                    ),
                  ),
                  child: Padding(
                    padding: const EdgeInsets.all(24.0),
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      crossAxisAlignment: CrossAxisAlignment.center,
                      children: [
                        TextField(
                            keyboardType: TextInputType.emailAddress,
                            decoration: InputDecoration(
                              border: OutlineInputBorder(
                                borderRadius: BorderRadius.all(
                                  Radius.circular(10.0),
                                ),
                                borderSide: BorderSide(
                                  width: 0,
                                  style: BorderStyle.none,
                                ),
                              ),
                              filled: true,
                              fillColor: Color(0xffe73ded),
                              hintText: "E-mail",
                              prefixIcon: Icon(
                                Icons.email,
                                color: Colors.grey,
                              ),
                            )),
                        SizedBox(
                          height: 20.0,
                        ),
                        TextField(
                            obscureText: _isVisible ? false :true,
                            keyboardType: TextInputType.visiblePassword,
                            decoration: InputDecoration(
                              suffixIcon: IconButton(
                                onPressed: () {
                                  setState(() {
                                    _isVisible = !_isVisible;
                                  });
                                },
                                icon: Icon(
                                  _isVisible ? Icons.visibility : Icons.visibility_off,
                                color: Colors.grey,
                                ),
                              ),
                              border: OutlineInputBorder(
                                borderRadius: BorderRadius.all(
                                  Radius.circular(10.0),
                                ),
                                borderSide: BorderSide(
                                  width: 0,
                                  style: BorderStyle.none,
                                ),
                              ),
                              filled: true,
                              fillColor: Color(0xffe73ded),
                              hintText: "Password",
                              prefixIcon: Icon(
                                Icons.lock_rounded,
                                color: Colors.grey,
                              ),
                            )),
                        SizedBox(
                          height: 5.0,
                        ),
                        Row(
                          mainAxisAlignment: MainAxisAlignment.end,
                          children: [
                            TextButton(
                              onPressed: () {},
                              child: Text(
                                'Forgot your password',
                                style: TextStyle(
                                  color: Colors.blue,
                                  decoration: TextDecoration.underline,
                                  decorationThickness: 2.0,
                                  decorationOffset: Offset(0, 2),
                                ),
                              ),
                            ),
                          ],
                        ),
                        SizedBox(
                          height: 20.0,
                        ),
                        ElevatedButton(
                          onPressed: () {},
                          style: ElevatedButton.styleFrom(
                            backgroundColor: Colors.blue,
                            shape: RoundedRectangleBorder(
                              borderRadius: BorderRadius.circular(28),
                            ),
                            minimumSize: Size(double.infinity, 0),
                            padding: EdgeInsets.symmetric(vertical: 16.0),
                          ),
                          child: Text(
                            'Login',
                            style: TextStyle(
                              color: Colors.white,
                              fontSize: 16.0,
                            ),
                          ),
                        ),
                        SizedBox( height: 2,),
                        RichText(
                          text: TextSpan(
                            text: 'Do you have an account?',
                            style: TextStyle(
                            color: Colors.black,
                            fontSize: 18,
                            ),
                            children: [
                              TextSpan(
                                  text: 'Register',
                                  style: TextStyle(
                                  color: Colors.blue,
                                  fontSize: 18,
                              ),
                                  recognizer: TapGestureRecognizer()
                                  ..onTap = () {}),
                             ],
                            ),
                           ),
                         ],
                       ),
                     ),
                   ),
                 ),
               ],
             ),
           ),
         ),
      );
    }
  }
}

内容的提问来源于stack exchange,提问作者jack

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 17:18:20