/ 應用編輯框你體驗過嗎? /
從各大應用市場下載的應用安裝完成后觸發打開應用的那一刻, 我們可能直接進入app進行查看app的功能模塊或者一開始就需要我們進行登錄操作才能進入app . 當進入app查看功能模塊時我們需要通過app快速查找對應的資訊 , 這時我們需要通過編輯框進行搜索 . 對編輯框進行編輯的時候可能是通過手機軟鍵盤一個字符一個字符的輸入到編輯框, 或者是直接從其它地方復制的文本到編輯框進行粘貼 , 搜索完成后切換成其它需要搜索的資訊時又需要快速洗掉再次快速編輯輸入框 . 不難發現一個簡單的編輯框是否做得好,直接影響了用戶的體驗 , 作為開發者最關系的是否能給用戶帶來好的體驗 .
自定義編輯框需要實作的幾個功能

/ Material Design TextField /
TextEditingController? controller
對輸入編輯框的文本進行控制 (例如 : 替換空格、一鍵洗掉文本、獲取編輯的值 等....)
TextEditingController 初始化在initState里面完成
TextEditingController? _controller; VoidCallback? _conListener; @override void initState() { super.initState(); _controller = TextEditingController(); _conListener = () { print('編輯輸入的值:' + _controller!.text); }; _controller!.addListener(_conListener!); }編輯框構建 build
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Center( child: Row( children: [ Expanded( child: TextField( controller: _controller, ), flex: 1, ), GestureDetector( onTap: () { _controller!.clear(); }, child: Container( padding: EdgeInsets.all(10.0), color: Colors.blue, child: Text('清除編輯框的文本'), ), ) ], ), ), ); }編輯框控制器銷毀
@override void dispose() { // TODO: implement dispose _controller!.clear(); _controller!.removeListener(_conListener!); _controller!.dispose(); _controller = null; super.dispose(); }![]()
輸入文本到編輯框 I/flutter ( 1091): 編輯輸入的值:我 I/flutter ( 1091): 編輯輸入的值:我已經 I/flutter ( 1091): 編輯輸入的值:我已經輸入值 I/flutter ( 1091): 編輯輸入的值:我已經輸入值到 I/flutter ( 1091): 編輯輸入的值:我已經輸入值到編輯框 I/flutter ( 1091): 編輯輸入的值:我已經輸入值到編輯框了![]()
點擊清除編輯框文本 I/flutter ( 1091): 編輯輸入的值:
FocusNode? focusNode
編輯框輸入獲取或失去焦點監聽 . 編輯框首次顯示輸入游標時默認為沒有獲取焦點 , 當進行了輸入操作后就等同于獲取了焦點 .
///編輯框獲取或者失去焦點監聽 VoidCallback? _focusNodeListener; FocusNode _focusNode = FocusNode(); @override void initState() { super.initState(); _controller = TextEditingController(); _conListener = () { print('編輯輸入的值:' + _controller!.text); }; _controller!.addListener(_conListener!); _focusNodeListener = () { print('編輯框是否獲取焦點:${_focusNode.hasFocus}'); }; _controller!.addListener(_focusNodeListener!); }TextField( controller: _controller, focusNode: _focusNode, ),編輯框首次顯示輸入游標時默認為沒有獲取焦點
I/flutter ( 8761): 編輯輸入的值: I/flutter ( 8761): 編輯框是否獲取焦點:false W/IInputConnectionWrapper( 8761): getSelectedText on inactive InputConnection W/IInputConnectionWrapper( 8761): getTextAfterCursor on inactive InputConnection W/IInputConnectionWrapper( 8761): getTextBeforeCursor on inactive InputConnection W/IInputConnectionWrapper( 8761): getTextAfterCursor on inactive InputConnection編輯框輸入文本或者洗掉文本后
I/flutter ( 8761): 編輯輸入的值:我正在 I/flutter ( 8761): 編輯框是否獲取焦點:true I/flutter ( 8761): 編輯輸入的值:我正在向 I/flutter ( 8761): 編輯框是否獲取焦點:true I/flutter ( 8761): 編輯輸入的值:我正在向編輯框 I/flutter ( 8761): 編輯框是否獲取焦點:true I/flutter ( 8761): 編輯輸入的值:我正在向編輯框輸入 I/flutter ( 8761): 編輯框是否獲取焦點:true I/flutter ( 8761): 編輯輸入的值:我正在向編輯框輸入值
InputDecoration? decoration
自定義編輯框樣式 (圖示、label、提示文本、錯誤文本、獲取焦點文本顏色、失去焦點文本顏色、字體樣式、邊框等.......)
InputDecoration({ this.icon, //位于裝飾器外部和輸入框前面的圖片 this.labelText, //用于描述輸入框,例如這個輸入框是用來輸入用戶名還是密碼的,當輸入框獲取焦點時默認會浮動到上方, this.labelStyle, // 控制labelText的樣式,接收一個TextStyle型別的值 this.helperText, //輔助文本,位于輸入框下方,如果errorText不為空的話,則helperText不會顯示 this.helperStyle, //helperText的樣式 this.hintText, //提示文本,位于輸入框內部 this.hintStyle, //hintText的樣式 this.hintMaxLines, //提示資訊最大行數 this.errorText, //錯誤資訊提示 this.errorStyle, //errorText的樣式 this.errorMaxLines, //errorText最大行數 this.hasFloatingPlaceholder = true, //labelText是否浮動,默認為true,修改為false則labelText在輸入框獲取焦點時不會浮動且不顯示 this.isDense, //改變輸入框是否為密集型,默認為false,修改為true時,圖示及間距會變小 this.contentPadding, //內間距 this.prefixIcon, //位于輸入框內部起始位置的圖示, this.prefix, //預先填充的Widget,跟prefixText同時只能出現一個 this.prefixText, //預填充的文本,例如手機號前面預先加上區號等 this.prefixStyle, //prefixText的樣式 this.suffixIcon, //位于輸入框后面的圖片,例如一般輸入框后面會有個眼睛,控制輸入內容是否明文 this.suffix, //位于輸入框尾部的控制元件,同樣的不能和suffixText同時使用 this.suffixText,//位于尾部的填充文字 this.suffixStyle, //suffixText的樣式 this.counter,//位于輸入框右下方的小控制元件,不能和counterText同時使用 this.counterText,//位于右下方顯示的文本,常用于顯示輸入的字符數量 this.counterStyle, //counterText的樣式 this.filled, //如果為true,則輸入使用fillColor指定的顏色填充 this.fillColor, //相當于輸入框的背景顏色 this.errorBorder, //errorText不為空,輸入框沒有焦點時要顯示的邊框 this.focusedBorder, //輸入框有焦點時的邊框,如果errorText不為空的話,該屬性無效 this.focusedErrorBorder, //errorText不為空時,輸入框有焦點時的邊框 this.disabledBorder, //輸入框禁用時顯示的邊框,如果errorText不為空的話,該屬性無效 this.enabledBorder, //輸入框可用時顯示的邊框,如果errorText不為空的話,該屬性無效 this.border, //正常情況下的border this.enabled = true, //輸入框是否可用 this.semanticCounterText, this.alignLabelWithHint, })decoration: const InputDecoration( icon: Icon(Icons.message),),![]()
icon 編輯框前面圖示 InputDecoration( labelText: '編輯框頂部提示文本' ),![]()
labelText InputDecoration( labelText: '編輯框頂部提示文本', labelStyle: TextStyle(color: Colors.red, fontSize: 14.0)),![]()
labelTextStyle InputDecoration( helperText: '編輯框底部提示文本', helperStyle: TextStyle(color: Colors.red, fontSize: 14.0))![]()
helperText / helperStyle 編輯框底部提示文本行數(顯示1行或者多行,如果文本值超過一行顯示省略號)
InputDecoration( helperMaxLines: 1, helperText: '編輯框底部提示文本/編輯框底部提示文本/編輯框底部提示文本/編輯框底部提示文本/編輯框底部提示文本', helperStyle: TextStyle(color: Colors.red, fontSize: 14.0))![]()
helperMaxLines InputDecoration( hintMaxLines: 1, hintText: '編輯框內提示文本/編輯框內提示文本/編輯框內提示文本/編輯框內提示文本', hintTextDirection: TextDirection.rtl, hintStyle: TextStyle(color: Colors.red, fontSize: 14.0))![]()
hintText / hintStyle / hintTextDirection / hintMaxLines InputDecoration( errorMaxLines: 1, errorText: '編輯框錯誤文本提示一', errorBorder: UnderlineInputBorder( borderRadius: BorderRadius.all( Radius.circular(30), //邊角為30 ), borderSide: BorderSide( color: Colors.amber, //邊線顏色為黃色 width: 2, //邊線寬度為2 ),), errorStyle: TextStyle(color: Colors.blue, fontSize: 14.0))![]()
errorMaxLines/errorText/errorBorder/errorStyle TextField( decoration: const InputDecoration( enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.all( Radius.circular(30), //邊角為30 ), borderSide: BorderSide( color: Colors.amber, //邊線顏色為紅色 width: 2, //邊線寬度為2 ), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.all( Radius.circular(30), //邊角為30 ), borderSide: BorderSide( color: Colors.green, //邊框顏色為綠色 width: 5, //寬度為5 ))), ),![]()
enabledBorder/focusedBorder
/ 自定義編輯框 /
編輯框一鍵洗掉
assets檔案夾下放置用來進行一鍵洗掉的圖示
pubspec.yaml 注冊圖示依賴
initState函式里面初始化一鍵洗掉編輯框控制器
//定義一個controller late TextEditingController _controller; bool _isShoDel = false; ///是否獲取焦點 bool _isFocus = false; FocusNode _focusNode = FocusNode(); @override void initState() { // TODO: implement initState super.initState(); _controller = TextEditingController(); _controller.addListener(() { _inputContro(_controller.text, false); }); _focusNode.addListener(() { print('輸入框是否獲取焦點: ${_focusNode.hasFocus}'); setState(() { _isFocus = _focusNode.hasFocus; }); }); }失去焦點或者編輯框不存在文本時 , 一鍵洗掉圖示隱藏
編輯框粘貼需用用到編輯控制器 , 復制文本粘貼到編輯會顯示一鍵洗掉
![]()
編輯框輸入文本后并失去焦點 , 一鍵洗掉按鈕隱藏
編輯框輸入完成后替換空格 ,網路請求資料只會上傳除開空格后的文本
編輯框完整編碼
import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; ///自定義編輯 class CusTextField extends StatefulWidget { final InputValueCallBack? _inputValueCallBack; ///編輯框輸入顏色值 final inputColorValue; ///編輯框默認提示文本 final hintText; ///邊框 final border; ///編輯框最外層邊框 final bgBorder; ///標題 final Widget? labelText; ///編輯框輸入文本大小 final inputFontSize; ///文本位置(左邊|右邊|中間) final TextAlign? textAlign; final keyboardType; //文本行數 final int? maxLine; ///邊框跟父視圖邊距 final margin; CusTextField(this._inputValueCallBack, {this.inputColorValue, this.hintText = '', this.border, this.bgBorder, this.labelText, this.inputFontSize, this.textAlign = TextAlign.right, this.maxLine = 1, this.margin, this.keyboardType}); @override _CusTextFieldState createState() => _CusTextFieldState(); } class _CusTextFieldState extends State<CusTextField> { //定義一個controller late TextEditingController _controller; bool _isShoDel = false; ///是否獲取焦點 bool _isFocus = false; FocusNode _focusNode = FocusNode(); @override void initState() { // TODO: implement initState super.initState(); _controller = TextEditingController(); _controller.addListener(() { _inputContro(_controller.text, false); }); _focusNode.addListener(() { print('輸入框是否獲取焦點: ${_focusNode.hasFocus}'); setState(() { _isFocus = _focusNode.hasFocus; }); }); } @override void dispose() { // TODO: implement dispose super.dispose(); } void _inputContro(v, bool isInput) { ///編輯框輸入文本長度 int _valueLength = '$v'.length; print('輸入框輸入監聽 文本長度: $_valueLength'); ///編輯框輸入文本大于0 _isShoDel = (_valueLength > 0); ///編輯框文本輸入文本存在值時或者等于為空時重繪編輯框 if (_valueLength <= 1 && isInput) { setState(() {}); print('CusTextField_重繪編輯框'); } ///粘貼 if (!isInput) { setState(() {}); } _inputValue(v); } @override Widget build(BuildContext context) { return Container( child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ widget.labelText ?? Container(), Expanded( flex: 1, child: Container( child: TextField( textAlign: (widget.textAlign)!, maxLines: widget.maxLine!, focusNode: _focusNode, ///游標顏色 cursorColor: Color(0xff005CFA), ///編輯框首次不自動獲取焦點 autofocus: false, keyboardType: widget.keyboardType ?? TextInputType.text, style: TextStyle( fontSize: widget.inputFontSize ?? 0.0, fontWeight: FontWeight.w400, ///文本輸入或文本為空時的顏色值 color: Color(_isShoDel ? 0xff1D1D1F : 0xffB8BABF)), decoration: InputDecoration( ///默認文本 hintText: '${widget.hintText ?? ''}', hintStyle: TextStyle( color: Color(0xffB8BABF), fontWeight: FontWeight.w400, ), ///邊框 border: widget.border ?? InputBorder.none, ), onChanged: (v) { _inputContro(v, true); }, controller: _controller, //設定controller ), ), ), Offstage( offstage: !(_isShoDel && _isFocus), child: GestureDetector( onTap: () { _controller.clear(); _inputContro('', false); }, child: Container( alignment: Alignment.center, width: 30.0, height: 40.0, color: Colors.transparent, child: Image.asset('assets/input_delete.png'), ), ), ), ], ), decoration: BoxDecoration( ///邊框 border: widget.bgBorder ?? InputBorder.none, ), margin: widget.margin ?? EdgeInsets.all(0.0), ); } void _inputValue(v) { String _curV = '$v'.replaceAll(' ', ''); print('編輯框輸入的值:$_curV'); ///編輯框輸入值 widget._inputValueCallBack!(_curV); } } ///編輯框輸入值 typedef void InputValueCallBack(var inputValue); bool isEmpty(String? s) { return (null == s || "" == s.toString().trim() || "null" == s || '{}' == s); }編輯框使用
class TextEditPage extends StatefulWidget { TextEditPage({Key? key, required this.title}) : super(key: key); final String title; @override _TextEditPageState createState() => _TextEditPageState(); } class _TextEditPageState extends State<TextEditPage> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Center( child: CusTextField((v) {}, hintText: '編輯框提示文本', margin: EdgeInsets.only(left: 10.0, right: 10.0), keyboardType: TextInputType.number, bgBorder: Border.all(color: Colors.green, width: 1.0), textAlign: TextAlign.start, inputFontSize: 14.0, labelText: Text('\t編輯框標題\t'))), ); } }
自定義編輯框案例下載
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/402781.html
標籤:其他
上一篇:Android開發復用代碼











