美文网首页
Flutter仿Boss-3.登录页

Flutter仿Boss-3.登录页

作者: 一笑轮回吧 | 来源:发表于2024-04-01 15:17 被阅读0次

    效果

    Screen_Recording_20240402-145821 (2).gif

    介绍

    在Flutter应用程序中创建登录页面对于用户认证和参与至关重要。登录页面作为用户访问应用程序功能的入口。它应该提供无缝的体验,同时确保安全和隐私。这里仿Boss应用设计的登录页面,我们将创建一个登录页面,允许用户使用手机号码登录或注册。

    小插曲

    首先,让我们设置Flutter项目并创建一个登录页面组件。我们将使用GetX进行状态管理和UI更新。确保您在开发环境中安装了Flutter和GetX。

    实现

    1. 依赖项

    确保您在pubspec.yaml文件中具有必要的依赖项:

    dependencies:
      flutter:
        sdk: flutter
      get: ^4.6.2
    

    2. 登录页小部件

    创建一个名为login_page.dart的新文件,并定义LoginPage小部件。此小部件将包含登录页面的UI元素:

    // login_page.dart
    class LoginPage extends StatelessWidget {
      const LoginPage({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        final logic = Get.find<LoginLogic>();
        return Scaffold(
          body: Container(
            padding: EdgeInsets.fromLTRB(24.w, 60.w, 24.w, 24.w),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  "手机号登录/注册",
                  style: TextStyle(
                    fontWeight: FontWeight.w500,
                    fontSize: 30.sp,
                    color: RC.text1Color,
                  ),
                ),
                SizedBox(height: 6.w),
                Text(
                  "首次验证通过即注册BOSS直聘账号",
                  style: TextStyle(
                    fontWeight: FontWeight.w500,
                    fontSize: 14.sp,
                    color: RC.text2Color,
                  ),
                ),
                SizedBox(height: 10.w),
                Row(
                  children: [
                    Text(
                      "+86",
                      style: TextStyle(
                        fontSize: 16.sp,
                        color: Colors.black,
                      ),
                    ),
                    Icon(
                      Icons.keyboard_arrow_down,
                      size: 25.w,
                      color: Colors.black.withAlpha(70),
                    ),
                    Expanded(
                      child: TextField(
                        controller: logic.controller,
                        keyboardType: TextInputType.phone,
                        inputFormatters: [
                          FilteringTextInputFormatter.allow(RegExp(r'[0-9]')),
                        ],
                        style: TextStyle(color: Colors.black, fontSize: 18.sp),
                        onChanged: (value) {
                          logic.state.phoneNum.value = value;
                        },
                        decoration: InputDecoration(
                          hintText: '请输入您的手机号码',
                          // 设置 hintText
                          hintStyle: TextStyle(color: Colors.grey, fontSize: 18.sp),
                          // 设置 hintText 的颜色
                          border: InputBorder.none,
                          // 取消底部下划线
                          enabledBorder: const OutlineInputBorder(
                            borderSide: BorderSide(
                                color: Colors.transparent), // 取消输入框选中时的边框颜色
                          ),
                          focusedBorder: const OutlineInputBorder(
                            borderSide: BorderSide(
                                color: Colors.transparent), // 取消输入框获取焦点时的边框颜色
                          ),
                        ),
                      ),
                    ),
                  ],
                ),
                Divider(
                  height: 1.w,
                  color: Colors.grey,
                ),
                SizedBox(height: 16.w),
                Obx(
                  () => InkWell(
                    onTap: () {
                      logic.state.isAgree.value = !logic.state.isAgree.value;
                    },
                    child: Row(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Padding(
                          padding: const EdgeInsets.only(top: 5),
                          child: Icon(
                            logic.state.isAgree.value
                                ? Icons.check_circle
                                : Icons.circle_outlined,
                            size: 18.r,
                            color: logic.state.isAgree.value
                                ? RC.themeColor
                                : Colors.grey,
                          ),
                        ),
                        SizedBox(width: 5.w),
                        Expanded(
                          child:
                          RichText(
                            text: TextSpan(
                              text: '已阅读并同意',
                              style: const TextStyle(
                                  color: Colors.black, fontSize: 16),
                              children: [
                                TextSpan(
                                  text: '《BOSS直聘用户协议》',
                                  style: const TextStyle(color: RC.themeColor),
                                  recognizer: TapGestureRecognizer()
                                    ..onTap = () {
                                      ToastUtil.show(msg: "跳转到BOSS直聘用户协议");
                                    },
                                ),
                                const TextSpan(
                                  text: ' 和 ',
                                  style:
                                      TextStyle(color: Colors.black, fontSize: 16),
                                ),
                                TextSpan(
                                  text: '《隐私政策》',
                                  style: const TextStyle(color: RC.themeColor),
                                  recognizer: TapGestureRecognizer()
                                    ..onTap = () {
                                      ToastUtil.show(msg: "跳转到隐私政策");
                                    },
                                ),
                                const TextSpan(
                                  text: ',允许BOSS直聘统一管理本人账号信息',
                                  style:
                                      TextStyle(color: Colors.black, fontSize: 16),
                                ),
                              ],
                            ),
                          ),
                        ),
                      ],
                    ),
                  ),
                ),
                Obx(
                  () => InkWell(
                    onTap: () {
                      logic.next(context);
                    },
                    child: Container(
                      height: 50.w,
                      alignment: Alignment.center,
                      margin: EdgeInsets.only(top: 20.w, bottom: 30.w),
                      decoration: BoxDecoration(
                          borderRadius: BorderRadius.all(Radius.circular(8.r)),
                          color: logic.state.phoneNum.isNotEmpty
                              ? RC.themeColor
                              : RC.themeColor.withAlpha(50)),
                      child: Text(
                        "下一步",
                        style: TextStyle(
                          fontSize: 20.sp,
                          fontWeight: FontWeight.w600,
                          color: Colors.white,
                        ),
                      ),
                    ),
                  ),
                ),
                Text(
                  "接受不到短信",
                  style: TextStyle(
                    fontSize: 14.sp,
                    color: Colors.grey,
                  ),
                ),
                Expanded(
                  child: Align(
                    alignment: Alignment.bottomCenter,
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.center,
                      mainAxisAlignment: MainAxisAlignment.end,
                      children: [
                        Text(
                          "或通过以下方式登录",
                          style: TextStyle(
                            fontSize: 14.sp,
                            color: Colors.grey,
                          ),
                        ),
                        SizedBox(height: 20.w),
                        InkWell(
                          onTap: () {
                            logic.wxLogin();
                          },
                          child: Image.asset(
                            R.login_wx_png,
                            width: 50.w,
                            height: 50.w,
                          ),
                        ),
                        SizedBox(height: 35.w),
                        Text(
                          "服务热线 举报监督电话 资质证照",
                          style: TextStyle(
                            fontSize: 14.sp,
                            color: Colors.grey,
                          ),
                        ),
                      ],
                    ),
                  ),
                ),
              ],
            ),
          ),
        );
      }
    }
    

    3. 登录页逻辑

    为登录页面创建一个逻辑类,用于处理业务逻辑和状态管理。定义处理用户输入和交互的方法:

    // logic.dart
    
    import 'package:flutter/material.dart';
    import 'package:get/get.dart';
    
    import 'util/toast_util.dart';
    
    class LoginLogic extends GetxController {
      final LoginState state = LoginState();
      final TextEditingController controller = TextEditingController();
    
      void wxLogin() {
        ToastUtil.show(msg: '微信登录');
      }
    
      void next(BuildContext context) {
        if (!state.isAgree.value) {
          showDialog(
            context: context,
            builder: (BuildContext context) {
              return AlertDialog(
                content: RichText(
                  text: TextSpan(
                    text: '请阅读并同意',
                    style: const TextStyle(color: Colors.black, fontSize: 16),
                    children: [
                      TextSpan(
                        text: '《BOSS直聘用户协议》',
                        style: const TextStyle(color: RC.themeColor),
                        recognizer: TapGestureRecognizer()
                          ..onTap = () {
                            ToastUtil.show(msg: "跳转到BOSS直聘用户协议");
                          },
                      ),
                      const TextSpan(
                        text: ' 和 ',
                        style: TextStyle(color: Colors.black, fontSize: 16),
                      ),
                      TextSpan(
                        text: '《隐私政策》',
                        style: const TextStyle(color: RC.themeColor),
                        recognizer: TapGestureRecognizer()
                          ..onTap = () {
                            ToastUtil.show(msg: "跳转到隐私政策");
                          },
                      ),
                      const TextSpan(
                        text: ',允许BOSS直聘统一管理本人账号信息',
                        style: TextStyle(color: Colors.black, fontSize: 16),
                      ),
                    ],
                  ),
                ),
                actions: <Widget>[
                  TextButton(
                    onPressed: () {
                      Navigator.of(context).pop();
                    },
                    child: const Text(
                      '拒绝',
                      style: TextStyle(
                        fontSize: 16,
                        color: RC.themeColor,
                      ),
                    ),
                  ),
                  TextButton(
                    onPressed: () {
                      state.isAgree.value = true;
                      Navigator.of(context).pop();
                    },
                    child: const Text(
                      '同意',
                      style: TextStyle(
                        fontSize: 16,
                        color: RC.themeColor,
                      ),
                    ),
                  ),
                ],
              );
            },
          );
          return;
        }
        ToastUtil.show(msg: '下一步');
      }
    }
    
    class LoginState {
      RxString phoneNum = "".obs;
      RxBool isAgree = false.obs;
    }
    

    4. 主程序入口

    在您的主文件中,将登录页面添加到应用程序的路由中:

    // main.dart
    
    import 'package:flutter/material.dart';
    import 'package:get/get.dart';
    
    import 'login_page.dart';
    import 'logic.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return GetMaterialApp(
          home: LoginPage(),
          initialBinding: BindingsBuilder(() {
            Get.lazyPut<LoginLogic>(() => LoginLogic());
          }),
        );
      }
    }
    

    结论

    通过以上步骤,我们已经完成了Boss登录页面的UI效果。

    相关文章

      网友评论

          本文标题:Flutter仿Boss-3.登录页

          本文链接:https://www.haomeiwen.com/subject/qrditjtx.html