Dart & Flutter 開發(fā)技巧 8-14
1568
2025-04-03
小菜最近在學(xué)習(xí)基礎(chǔ)的 flutter Widget,原因在于很多基礎(chǔ)的組件有很多容易忽視的注意事項,了解并熟悉后對整體的開發(fā)認(rèn)知會有所提升;今天小菜學(xué)習(xí)一下 TextField 文本輸入框;
源碼分析
const TextField({ Key key, this.controller, // 控制正在編輯文本 this.focusNode, // 獲取鍵盤焦點 this.decoration = const InputDecoration(), // 邊框裝飾 TextInputType keyboardType, // 鍵盤類型 this.textInputAction, // 鍵盤的操作按鈕類型 this.textCapitalization = TextCapitalization.none, // 配置大小寫鍵盤 this.style, // 輸入文本樣式 this.textAlign = TextAlign.start, // 對齊方式 this.textDirection, // 文本方向 this.autofocus = false, // 是否自動對焦 this.obscureText = false, // 是否隱藏內(nèi)容,例如密碼格式 this.autocorrect = true, // 是否自動校正 this.maxLines = 1, // 最大行數(shù) this.maxLength, // 允許輸入的最大長度 this.maxLengthEnforced = true, // 是否允許超過輸入最大長度 this.onChanged, // 文本內(nèi)容變更時回調(diào) this.onEditingComplete, // 提交內(nèi)容時回調(diào) this.onSubmitted, // 用戶提示完成時回調(diào) this.inputFormatters, // 驗證及格式 this.enabled, // 是否不可點擊 this.cursorWidth = 2.0, // 光標(biāo)寬度 this.cursorRadius, // 光標(biāo)圓角弧度 this.cursorColor, // 光標(biāo)顏色 this.keyboardAppearance, // 鍵盤亮度 this.scrollPadding = const EdgeInsets.all(20.0), // 滾動到視圖中時,填充邊距 this.enableInteractiveSelection, // 長按是否展示【剪切/復(fù)制/粘貼菜單LengthLimitingTextInputFormatter】 this.onTap, // 點擊時回調(diào) })
分析源碼可得,TextField 是有狀態(tài) StatefulWidget,有豐富的屬性,自定義化較高,實踐中需要合理利用各種回調(diào);
案例嘗試
小菜嘗試最基本的 TextField,區(qū)分默認(rèn)狀態(tài)和獲取焦點狀態(tài);
return TextField();
小菜嘗試了光標(biāo)的相關(guān)屬性;cursorColor 為光標(biāo)顏色,cursorWidth 為光標(biāo)寬度,cursorRadius 為光標(biāo)圓角;其中 Radius 提供了 circle 圓角和 elliptical 非圓角兩種;
return TextField(cursorColor: Colors.purple.withOpacity(0.4), cursorWidth: 10.0, cursorRadius: Radius.circular(4.0));
textAlign 為文字起始位置,可根據(jù)業(yè)務(wù)光標(biāo)居左/居右/居中等;注意只是文字開始方向;textDirection 問文字內(nèi)容方向,從左向右或從右向左;
return TextField(style: TextStyle(color: Colors.purple.withOpacity(0.7), fontSize: 18.0), textAlign: TextAlign.right);
maxLength 為字符長度,設(shè)置時默認(rèn)是展示一行,且右下角有編輯長度與整體長度對比;與 maxLengthEnforced 配合,maxLengthEnforced 為 true 時達到最大字符長度后不可編輯;為 false 時可繼續(xù)編輯展示有差別;
return TextField(maxLength: 30, maxLengthEnforced: true); return TextField(maxLength: 30, maxLengthEnforced: false);
設(shè)置 maxLength 之后右下角默認(rèn)有字符計數(shù)器,設(shè)置 TextField.noMaxLength 即可只展示輸入字符數(shù);
return TextField(maxLength: TextField.noMaxLength);
maxLines 為允許展現(xiàn)的最大行數(shù),在使用 maxLength 時內(nèi)容超過一行不會自動換行,因為默認(rèn) maxLines=1,此時設(shè)置為 null 或固定展示行數(shù)即可自動換行;區(qū)別在于 null 會展示多行,而 maxLines 最多只展示到設(shè)置行數(shù);
return TextField(maxLength: 130, maxLengthEnforced: false, maxLines: null); return TextField(maxLength: 130, maxLengthEnforced: false, maxLines: 2);
obscureText 是否隱藏編輯內(nèi)容,常見的密碼格式;
return TextField(obscureText: true);
enableInteractiveSelection 長按是否出現(xiàn)【剪切/復(fù)制/粘貼】菜單;不可為空;
return TextField(enableInteractiveSelection: false);
keyboardAppearance 為鍵盤亮度,包括 Brightness.dark/light 兩種,但僅限于 iOS 設(shè)備;
return TextField(keyboardAppearance: Brightness.dark);
textCapitalization 文字大小寫;理論上 sentences 為每句話第一個字母大寫;characters 為每個字母大寫;words 為每個單詞首字母大寫;但該屬性僅限于 text keybord,小菜在本地更換多種方式并未實現(xiàn),有待研究;
return TextField(textCapitalization: TextCapitalization.sentences);
keyboardType 為鍵盤類型,小菜理解整體分為數(shù)字鍵盤和字母鍵盤等;根據(jù)設(shè)置的鍵盤類型,鍵盤會有差別;
a. 數(shù)字鍵盤
–1-- datetime 鍵盤上可隨時訪問 : 和 /;
–2-- phone 鍵盤上可隨時訪問 # 和 *;
–3-- number 鍵盤上可隨時訪問 + - * /
b. 字母鍵盤
–1-- emailAddress 鍵盤上可隨時訪問 @ 和 .;
–2-- url 鍵盤上可隨時訪問 / 和 .;
–3-- multiline 適用于多行文本換行;
–4-- text 默認(rèn)字母鍵盤;
return TextField(keyboardType: TextInputType.number); return TextField(keyboardType: TextInputType.emailAddress);
textInputAction 通常為鍵盤右下角操作類型,小菜以前稍微整理過,類型眾多,建議多多嘗試;
return TextField(textInputAction: TextInputAction.search);
autofocus 是否自動獲取焦點,進入頁面優(yōu)先獲取焦點,并彈出鍵盤,若頁面中有多個 TextField 設(shè)置 autofocus 為 true 則優(yōu)先獲取第一個焦點;
return TextField(autofocus: true);
focusNode 手動獲取焦點,可配合鍵盤輸入等減少用戶操作次數(shù),直接獲取下一個 TextField 焦點;
FocusScope.of(context).requestFocus(node); return TextField(focusNode: node);
enabled 設(shè)為 false 之后 TextField 為不可編輯狀態(tài);
return TextField(enabled: false);
decoration 為邊框修飾,可以借此來調(diào)整 TextField 展示效果;可以設(shè)置前置圖標(biāo),后置圖片,邊框?qū)傩裕瑑?nèi)容屬性等,小菜會在后續(xù)集中嘗試;若要完全刪除裝飾,將 decoration 設(shè)置為空即可;
return TextField(decoration: InputDecoration(icon: Icon(Icons.android)));
inputFormatters 為格式驗證,例如原生 Android 中通常會限制輸入手機號或其他特殊字符,在 flutter 中也可以借此來進行格式限制,包括正則表達式;使用時需要引入 package:flutter/services.dart;
a. LengthLimitingTextInputFormatter 限制最長字符;
b. WhitelistingTextInputFormatter 僅允許輸入白名單中字符;如 digitsOnly 僅支持?jǐn)?shù)字 [0-9];
c. BlacklistingTextInputFormatter 防止輸入黑名單中字符;如 singleLineFormatter 強制輸入單行;分析源碼 RegExp("[/\]") 可以設(shè)置正則表達式;
return TextField(inputFormatters:
onChanged 文本內(nèi)容變更時回調(diào),可實時監(jiān)聽 TextField 輸入內(nèi)容;
Center(child: Text(_textStr)) return TextField(onChanged: (text) { setState(() { _textStr = text; }); });
controller 文本控制器,監(jiān)聽輸入內(nèi)容回調(diào);
TextEditingController controller = TextEditingController(); @override void initState() { super.initState(); controller.addListener(() { setState(() { _textStr = controller.text; }); }); } return TextField(controller: controller);
onTap 點擊 TextField時回調(diào);
return TextField( onTap: () { Toast.show('onTap!', context, duration: Toast.LENGTH_SHORT, gravity: Toast.TOP); }, );
onEditingComplete 在提交內(nèi)容時回調(diào),通常是點擊回車按鍵時回調(diào);
return TextField( onEditingComplete: () { Toast.show('onEditingComplete!', context, duration: Toast.LENGTH_SHORT, gravity: Toast.CENTER); }, );
onSubmit 在提交時回調(diào),不可與 onEditingComplete 同時使用,區(qū)別在于 onSubmit 是帶返回值的回調(diào);
return TextField( onEditingComplete: () { Toast.show('onSubmitted -> $text!', context, duration: Toast.LENGTH_SHORT, gravity: Toast.CENTER); }, );
問題小結(jié)
當(dāng) TextField 獲取焦點彈出輸入框時,輸入框可能會將頁面中元素頂上去,為避免此情況,可將 Scaffold 中 resizeToAvoidBottomPadding: false 即可,resizeToAvoidBottomPadding 設(shè)置是否自動調(diào)整body屬性控件的大小,以避免 Scaffold 底部被覆蓋;
resizeToAvoidBottomPadding: false
resizeToAvoidBottomPadding: true
當(dāng) TextField 設(shè)置 enableInteractiveSelection 屬性后長按會出現(xiàn)菜單,默認(rèn)為英文,可通過設(shè)置 Flutter 國際化來處理;
在 pubspec.yaml 中集成 flutter_localizations;
dependencies: flutter: sdk: flutter flutter_localizations: sdk: flutter
在 MaterialApp 中設(shè)置本地化代理和支持的語言類型;
return MaterialApp( localizationsDelegates: [ GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, ], supportedLocales: [ const Locale('zh', 'CN'), const Locale('en', 'US'), ] }
將 maxLength 設(shè)置為 null 僅使用 LengthLimitingTextInputFormatter 限制最長字符;
return TextField(maxLength: null, inputFormatters:
設(shè)置 InputDecoration 中 **** 屬性為空;但是底部有空余,只是隱藏而并非消失;
return TextField(decoration: InputDecoration(counterText: ""), maxLength: 10);
文本框是日常開發(fā)中必不可少的組件,小菜還在探索過程中,如有問題請多多指導(dǎo)!
來源: 阿策小和尚
Flutter
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。