import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; class LoginPhoneTextField extends StatelessWidget { const LoginPhoneTextField( {Key? key, required this.controller, this.helperText, this.rightWidget}) : super(key: key); final TextEditingController controller; final String? helperText; final Widget? rightWidget; @override Widget build(BuildContext context) { Widget textField = SizedBox( height: 40, child: TextFieldBase( keyboardType: TextInputType.number, leftWidget: const Padding( padding: EdgeInsets.only(left: 10), child: Icon( Icons.perm_contact_calendar_sharp, color: Colors.grey, size: 20, ), ), rightWidget: rightWidget, hintText: '请输入账号', style: const TextStyle(color: Colors.white), controller: controller, ), ); return helperText == null ? textField : Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ textField, Padding( padding: const EdgeInsets.only(top: 5), child: Text( helperText!, style: const TextStyle(fontSize: 12, color: Colors.grey), ), ) ], ); } } class LoginPasswordTextField extends StatefulWidget { const LoginPasswordTextField( {Key? key, required this.controller, this.hintText = '请输入密码', this.onSubmitted}) : super(key: key); final TextEditingController controller; final String hintText; final ValueChanged? onSubmitted; @override State createState() => _LoginPasswordTextFieldState(); } class _LoginPasswordTextFieldState extends State { bool hideCancel = true; bool obsureText = true; @override Widget build(BuildContext context) { Widget cancel = Offstage( offstage: hideCancel, child: TextButton( style: ButtonStyle( overlayColor: MaterialStateProperty.all(Colors.transparent), ), onPressed: () { setState(() { obsureText = !obsureText; }); }, child: Icon( Icons.remove_red_eye_rounded, color: Colors.grey, size: 20, ), ), ); widget.controller.addListener(() { setState(() { hideCancel = !widget.controller.text.isNotEmpty; }); }); return SizedBox( height: 40, child: TextFieldBase( hintText: widget.hintText, controller: widget.controller, obsureText: obsureText, onSubmitted: widget.onSubmitted, leftWidget: const Padding( padding: EdgeInsets.only(left: 10), child: Icon( Icons.lock_sharp, color: Colors.grey, size: 20, ), ), style: const TextStyle(color: Colors.white), rightWidget: cancel, ), ); } } class TextFieldBase extends StatefulWidget { const TextFieldBase( {Key? key, this.leftWidget, this.rightWidget, this.hintText = '', required this.controller, this.obsureText = false, this.keyboardType, this.textAlign = TextAlign.start, this.onChanged, this.onSubmitted, this.inputFormatters, this.focusNode, this.decoration, this.style, this.noFocusSubmitted = false}) : super(key: key); final TextEditingController controller; final FocusNode? focusNode; final Widget? leftWidget; final Widget? rightWidget; final InputDecoration? decoration; final TextStyle? style; final TextInputType? keyboardType; final String hintText; /// 暗文 final bool obsureText; final TextAlign textAlign; final List? inputFormatters; /// 失去焦点是否回调 final bool noFocusSubmitted; final ValueChanged? onChanged; final ValueChanged? onSubmitted; @override State createState() => _TextFieldBaseState(); } class _TextFieldBaseState extends State { late FocusNode focusNode; @override void initState() { super.initState(); focusNode = widget.focusNode ?? FocusNode(); if (widget.onSubmitted != null && widget.noFocusSubmitted){ focusNode.addListener(() { if (focusNode.hasFocus == false){ widget.onSubmitted!(widget.controller.text); } }); } } @override Widget build(BuildContext context) { final decoration = widget.decoration ?? InputDecoration( prefixIcon: widget.leftWidget, prefixIconConstraints: const BoxConstraints(minWidth: 4), suffixIcon: widget.rightWidget, hintText: widget.hintText, hintStyle: const TextStyle(color: Colors.grey), border: MaterialStateOutlineInputBorder.resolveWith((states) => const OutlineInputBorder( borderSide: BorderSide(color: Colors.grey))), contentPadding: const EdgeInsets.only(left: 0, top: 0, bottom: 0, right: 15), ); return TextField( focusNode: focusNode, controller: widget.controller, inputFormatters: widget.inputFormatters, style: widget.style ?? const TextStyle(fontSize: 14), keyboardType: widget.keyboardType, obscureText: widget.obsureText, textAlign: widget.textAlign, cursorColor: Colors.blue, onChanged: widget.onChanged, onSubmitted: widget.onSubmitted, decoration: decoration, ); } }