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

如何修改Flutter中AWS Authentication包的UI/UX?

在Flutter中自定义AWS Authentication包的UI/UX

AWS Amplify Flutter的Auth模块提供了两种自定义UI/UX的方式,根据你的需求选择即可:


一、快速调整预构建UI的样式

如果只是想修改颜色、字体、组件样式,不需要完全重写表单,可以通过自定义主题来调整预构建UI:

  • 定义自定义主题实例

    final customAuthTheme = AmplifyTheme(
      primaryColor: Colors.deepPurple,
      secondaryColor: Colors.purpleAccent,
      textTheme: const TextTheme(
        headlineLarge: TextStyle(fontFamily: 'Inter', fontSize: 26, fontWeight: FontWeight.w600),
        bodyLarge: TextStyle(color: Colors.grey.shade800, fontSize: 14),
      ),
      buttonTheme: ButtonThemeData(
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
        buttonColor: Colors.deepPurple,
        textTheme: ButtonTextTheme.primary,
      ),
      inputDecorationTheme: InputDecorationTheme(
        border: OutlineInputBorder(borderRadius: BorderRadius.circular(8)),
        focusedBorder: OutlineInputBorder(
          borderSide: BorderSide(color: Colors.deepPurple, width: 2),
        ),
        hintStyle: TextStyle(color: Colors.grey.shade500),
      ),
    );
    
  • 加载预构建UI时传入主题

    AmplifyAuthUI().signIn(
      theme: customAuthTheme,
      onSignInComplete: (result) {
        // 处理登录完成逻辑
      },
    );
    

二、完全自定义表单(高度定制)

如果需要完全控制布局、交互逻辑,建议自己构建表单,直接调用Amplify Auth的底层API:

1. 自定义登录表单

// 自定义登录界面(示例)
class CustomLoginScreen extends StatefulWidget {
  @override
  State<CustomLoginScreen> createState() => _CustomLoginScreenState();
}

class _CustomLoginScreenState extends State<CustomLoginScreen> {
  final _usernameController = TextEditingController();
  final _passwordController = TextEditingController();

  Future<void> _handleSignIn() async {
    try {
      final result = await Amplify.Auth.signIn(
        username: _usernameController.text,
        password: _passwordController.text,
      );
      if (result.isSignedIn) {
        // 登录成功,跳转主页
        Navigator.pushReplacementNamed(context, '/home');
      } else {
        // 处理MFA等额外验证逻辑
      }
    } on AuthException catch (e) {
      // 提示用户错误信息,比如"用户名或密码错误"
      ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(e.message)));
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Padding(
        padding: const EdgeInsets.all(24.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            TextFormField(
              controller: _usernameController,
              decoration: const InputDecoration(hintText: '用户名/邮箱'),
            ),
            const SizedBox(height: 16),
            TextFormField(
              controller: _passwordController,
              obscureText: true,
              decoration: const InputDecoration(hintText: '密码'),
            ),
            const SizedBox(height: 24),
            ElevatedButton(
              onPressed: _handleSignIn,
              child: const Text('登录'),
            ),
            TextButton(
              onPressed: () => Navigator.pushNamed(context, '/forgot-password'),
              child: const Text('忘记密码?'),
            ),
            TextButton(
              onPressed: () => Navigator.pushNamed(context, '/signup'),
              child: const Text('还没有账号?立即注册'),
            ),
          ],
        ),
      ),
    );
  }
}

2. 自定义注册表单

Future<void> _handleSignUp(String username, String password, String email) async {
  try {
    final userAttributes = <AuthUserAttributeKey, String>{
      AuthUserAttributeKey.email: email,
    };
    final result = await Amplify.Auth.signUp(
      username: username,
      password: password,
      options: SignUpOptions(userAttributes: userAttributes),
    );
    if (result.isSignUpComplete) {
      // 注册完成,自动登录
      await Amplify.Auth.signIn(username: username, password: password);
      Navigator.pushReplacementNamed(context, '/home');
    } else {
      // 跳转邮箱/手机验证页面
      Navigator.pushNamed(context, '/verify-code', arguments: username);
    }
  } on AuthException catch (e) {
    ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(e.message)));
  }
}

3. 自定义找回密码流程

// 发起密码重置请求
Future<void> _sendResetCode(String username) async {
  try {
    await Amplify.Auth.resetPassword(username: username);
    Navigator.pushNamed(context, '/confirm-reset', arguments: username);
  } on AuthException catch (e) {
    ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(e.message)));
  }
}

// 确认密码重置
Future<void> _confirmResetPassword(String username, String newPassword, String code) async {
  try {
    await Amplify.Auth.confirmResetPassword(
      username: username,
      newPassword: newPassword,
      confirmationCode: code,
    );
    // 重置成功,跳转登录页
    Navigator.pushReplacementNamed(context, '/login');
  } on AuthException catch (e) {
    ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(e.message)));
  }
}

4. 自定义登出功能

Future<void> _handleSignOut() async {
  try {
    await Amplify.Auth.signOut();
    Navigator.pushReplacementNamed(context, '/login');
  } on AuthException catch (e) {
    ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(e.message)));
  }
}

三、注意事项

  • 确保已完成Amplify Auth的初始化:
    await Amplify.addPlugin(AmplifyAuth());
    await Amplify.configure(amplifyconfig);
    
  • 针对表单输入添加基础验证(比如密码长度、邮箱格式),提升用户体验
  • 处理所有AuthException场景,给用户明确的错误提示

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 11:05:17