Skip to content

1.5 路由+登录、注册界面

涉及内容

  • 静态路由
  • 带阴影的椭圆图标
  • 输入有效性校验
  • 组件抽取方法
  • 通用组件、业务组件
  • 程序目录组织
  • 抽取透明导航栏
  • toast提示组件

下面说的文件,意味着已创建(没有就去创建它)。

输入框TextField

静态路由

跳转:

Navigator.pushNamed(
    context,
    "sign-up"
)

返回上一页:

Navigator.pop(context)

组件抽取方法

  • 抽取按钮:自定义扁平圆角按钮btnFlatButtonWidget第三方按钮btnFlatButtonBorderOnlyWidgetlib/common/widgets/button.dart文件里。 lib/common/widgets/button.dart代码如下:
import 'package:flutter/material.dart';
import 'package:flutter_demo_getx_learn/common/index.dart';
/// 扁平圆角按钮
Widget btnFlatButtonWidget({
  required VoidCallback onPressed,
  double width = 140,
  double height = 44,
  Color gbColor = AppColors.primaryElement,
  String title = "button",
  Color fontColor = AppColors.primaryElementText,
  double fontSize = 18,
  String fontName = "Montserrat",
  FontWeight fontWeight = FontWeight.w400,
  EdgeInsetsGeometry margin = const EdgeInsets.all(0),
}) {
  return Container(
    margin: margin,
    width: ScreenAdapter.setWidth(width),
    height: ScreenAdapter.setHeight(height),
    child: TextButton(
      onPressed: onPressed,
      style: ButtonStyle(
        //文字颜色
        foregroundColor: MaterialStateProperty.resolveWith((states){
          if (states.contains(MaterialState.focused) &&
                !states.contains(MaterialState.pressed)) {
                  // print(111);
                  // print(MaterialState.focused);
                  // print(MaterialState.pressed);
              return Colors.blue;
            } else if (states.contains(MaterialState.pressed)) {
              // print(222);
              return Colors.deepPurple;
            }
            // print(333);
            return fontColor;
        }),
        //背景颜色
        backgroundColor: MaterialStateProperty.resolveWith((states) {
          if (states.contains(MaterialState.pressed)) {
            return Colors.blue[200];
          }
          return gbColor;
        }),
        shape: MaterialStateProperty.all(const RoundedRectangleBorder(
          borderRadius: AppRadius.k6pxRadius,
        )),
      ),
      child: Text(
        title,
        style: TextStyle(
          fontFamily: fontName,
          fontWeight: fontWeight,
          fontSize: ScreenAdapter.setFontSize(fontSize),
          height: 1, // 设置下行高,否则字体下沉
        ),
      ),
    ),
  );
}
/// 第三方按钮
Widget btnFlatButtonBorderOnlyWidget({
  required VoidCallback onPressed,
  double width = 140,
  double height = 44,
  required String iconFileName,
  EdgeInsetsGeometry margin = const EdgeInsets.all(0),
}) {
  return Container(
    margin: margin,
    width: ScreenAdapter.setWidth(88),
    height: ScreenAdapter.setHeight(44),
    child: TextButton(
      onPressed: onPressed, 
      style: ButtonStyle(
        //设置圆角
        shape: MaterialStateProperty.all(const RoundedRectangleBorder(
          borderRadius: AppRadius.k6pxRadius,
        )),
        //边框的宽度 和 颜色
        side: MaterialStateProperty.all(
          Borders.primaryBorder
        )
      ),
      child: Image.asset(
        "assets/images/icons-$iconFileName.png",
      ),
    ),
  );
}
  • 抽取input:自定义输入框inputTextEditlib/common/widgets/input.dart文件里。 lib/common/widgets/input.dart代码如下:
import 'package:flutter/material.dart';
import 'package:flutter_demo_getx_learn/common/index.dart';

/// 输入框
Widget inputTextEdit({
  TextEditingController? controller,
  TextInputType keyboardType = TextInputType.text,
  String? hintText,
  bool isPassword = false,
  double marginTop = 15,
  bool autofocus = false,
}) {
  return Container(
    height: ScreenAdapter.setHeight(44), // 设置TextField的高度
    margin: EdgeInsets.only(top: ScreenAdapter.setHeight(marginTop)),
    decoration: const BoxDecoration(
      color: AppColors.secondaryElement,
      borderRadius: AppRadius.k6pxRadius
    ),
    child: TextField(
      controller: controller,
      keyboardType: keyboardType,
      autofocus: autofocus,
      autocorrect: false, // 自动纠正
      maxLines: 1,
      // 使用obscureText属性来隐藏密码输入
      obscureText: isPassword, // 隐藏输入内容, 密码框
      style: TextStyle(
        color: AppColors.primaryText,
        fontFamily: "Avenir",
        fontWeight: FontWeight.w400,
        fontSize: ScreenAdapter.setFontSize(18),
      ),
      decoration: InputDecoration(
        hintText: hintText,
        // 内容的内边距
        contentPadding: EdgeInsets.fromLTRB(
          ScreenAdapter.setHeight(20), 
          ScreenAdapter.setHeight(10), 
          0, 
          ScreenAdapter.setHeight(9)
        ),
        // contentPadding: const EdgeInsets.fromLTRB(20, 4, 0, 6),
        border: InputBorder.none,
      )
    )
  );
}
  • 抽取透明导航栏:自定义transparentAppBar(透明背景AppBar)lib/common/widgets/app.dart文件里。 lib/common/widgets/app.dart代码如下:
import 'package:flutter/material.dart';
/// 透明背景 AppBar
AppBar transparentAppBar({
  Widget? title,
  Widget? leading,
  List<Widget>? actions,
}) {
  return AppBar(
    backgroundColor: Colors.transparent,
    title: title!=null ? Center(
      child: title,
    ) : null,
    leading: leading, // 左侧
    actions: actions, // 右侧
  );
}
  • 抽取组件lib/common/widgets/toast.dart文件:toast提示组件的二次封装

输入有效性校验

lib/common/utils/validator.dart文件里自定义校验方法:

  • duIsEmail(检查邮箱格式)
  • duCheckStringLength(检查字符长度)

toast提示组件

使用的 用户交互 插件 是 fluttertoast使用文档。 在 pubspec.yaml里配置:

yaml
dependencies:
  flutter:
    sdk: flutter
  # toast
  fluttertoast: ^8.2.5

lib/common/widgets/dart.dart文件里进行二次封装,代码如下:

import 'package:flutter/material.dart';
import 'package:flutter_demo_getx_learn/common/index.dart';
import 'package:fluttertoast/fluttertoast.dart';

Future<bool?> toastInfo({
  String msg = "msg",
  Color backgroundColor = Colors.black,
  Color textColor = Colors.white,
}) {
  return Fluttertoast.showToast(
    msg: msg,
    toastLength: Toast.LENGTH_SHORT,
    gravity: ToastGravity.CENTER,
    timeInSecForIosWeb: 1,
    backgroundColor: backgroundColor,
    textColor: textColor,
    fontSize: ScreenAdapter.setFontSize(16)
  );
}

创作不易请尊重他人劳动成果,未经授权禁止转载!
Released under the MIT License.