跳至主要內容

封装TextField

chanchaw大约 2 分钟flutter

概述

自己封装 TextField 涉及到的知识点

  • 声明回调函数时使用的数据类型

code

下面是文件 input_widget.dart 的代码,用于封装 TextField

import 'package:flutter/material.dart';

class InputWidget extends StatelessWidget {
  // const InputWidget({super.key});

  final String? placeHolder;
  final bool isPwd;

  // 文本框中内容变动事件
  final ValueChanged<String>? onChanged;
  // 文本框输入内容的类型
  // 例如在账号/密码文本框中只能输入
  // 字符数字和符号 - 不能输入中文
  final TextInputType? keyboardType;

  final FocusNode? focusNode;
  final ValueChanged<String>? onFieldSubmitted;

  // 构造方法,在花括号内的属性都是可选的
  // 可通过 required 标识为必填(也可以将属性前置到花括号外面,表示必填)
  // 也可以设置默认值
  const InputWidget({
    Key? key,
    required this.placeHolder,
    this.onChanged,
    this.isPwd = false,
    this.keyboardType, this.focusNode, this.onFieldSubmitted
  }):super(key:key);

  
  Widget build(BuildContext context) {
    return Column(
      children: [
        _input(),
        const Divider(
          color: Colors.white, height: 1, thickness: 0.5,
        )
      ],
    );
  }

  _input() {
    return TextField(
      onChanged: onChanged, obscureText: isPwd, keyboardType: keyboardType, autofocus: !isPwd, cursorColor: Colors.white,
      focusNode: focusNode, onSubmitted: onFieldSubmitted,
      style: const TextStyle(// 文本样式
        fontSize: 17, color: Colors.white, fontWeight: FontWeight.w400,
      ),
      decoration: InputDecoration(// Input widget 样式
        border: InputBorder.none, hintText: placeHolder, hintStyle: const TextStyle(fontSize: 17, color: Colors.grey)
      ),
    );
  }
}

下面是 login_page.dart 的部分代码,用于演示如何使用上面封装的 InputWidget

_content() {
    return Positioned.fill(
        left: 25, right: 25,
        child: ListView(// 可拖拽移位
            children: [
                SizedBox(height: 100),
                const Text('账号密码登录', style: TextStyle(fontSize: 26, color: Colors.white),),
                SizedBox(height: 100),
                // 账号
                InputWidget(
                    placeHolder: '请输入登录账号',
                    focusNode: _usernameFocus,
                    onFieldSubmitted:  (value) { // 添加提交回调
                        FocusScope.of(context).requestFocus(_passwordFocus);
                    },
                    onChanged: (text){
                        username = text;
                        print('username:$username');
                        print('userIsEmpty:${isEmpty(username)}');
                        _isBtnEnable();// 设置登录按钮是否可用
                    },),

                // 密码
                InputWidget(
                    placeHolder: '请输入密码', isPwd: true,
                    focusNode: _passwordFocus,
                    onFieldSubmitted:  (value) { // 添加提交回调
                        if(loginEnable) _login();
                    },
                    onChanged: (text){
                        password = text;
                        _isBtnEnable();
                    }
                ),
                SizedBox(height: 50),
                // 调用函数几种方式:
                // onPressed: () => _login()
                // onPressed: _login        仅仅是函数名称
                LoginButton('登录', enable: loginEnable, onPressed: () => _login(),),
                SizedBox(height: 25),
                Align(
                    alignment: Alignment.centerRight,
                    child: InkWell(
                        onTap: () => _gotoRegistration(),
                        child: const Text('注册账号', style: TextStyle(color: Colors.white))
                    ),

                )
            ]
        )
    );
}