輸入框 TextField
TextField用於文本輸入,它提供了很多屬性:
const TextField({
Key key,
this.controller,// 控制器
this.focusNode, // 控制TextField是否佔有當前鍵盤的輸入焦點
this.decoration = const InputDecoration(), // 控制TextField的外觀顯示
TextInputType keyboardType,// 輸入框默認的鍵盤輸入類型
this.textInputAction,
this.textCapitalization = TextCapitalization.none,
this.style,//輸入文本的樣式
this.strutStyle,
this.textAlign = TextAlign.start,//文本對齊方式
this.textAlignVertical,
this.textDirection,
this.readOnly = false,
ToolbarOptions toolbarOptions,
this.showCursor,// 顯示光標
this.autofocus = false,//是否自動對焦
this.obscureText = false,//是否隱藏輸入的內容
this.autocorrect = true,//是否自動更正
this.enableSuggestions = true,
this.maxLines = 1,// 最大行數
this.minLines,//最小行數
this.expands = false,
this.maxLength,//最大長度
this.maxLengthEnforced = true,
this.onChanged,// 輸入框變化回調
this.onEditingComplete,// 編輯完成回調
this.onSubmitted,// 提交回調
this.inputFormatters,//允許的輸入格式
this.enabled,//是否禁用textfield
this.cursorWidth = 2.0,// 光標寬度
this.cursorRadius,//光標半徑
this.cursorColor,//光標顏色
this.keyboardAppearance,
this.scrollPadding = const EdgeInsets.all(20.0),
this.dragStartBehavior = DragStartBehavior.start,
this.enableInteractiveSelection = true,
this.onTap,
this.buildCounter,
this.scrollController,
this.scrollPhysics,
})
字段太多了,我們從幾個示例來了解主要字段的使用。
默認效果
只有一條下劃線,也沒有自動獲取焦點。
TextField();
監聽內容變化,獲取輸入框的內容
如果我們要獲取輸入的內容,這時候可以通過onChange, onSubmitted
,僞代碼如下:
Widget _buildTextField(){
return TextField(
onChanged: (text) {
//內容改變的回調
print('change $text');
},
onEditingComplete:(){
print('editing ');
},
onSubmitted: (text) {
//內容提交(按回車)的回調
print('submit $text');
},
);
}
和鍵盤的交互
默認獲取焦點
只需要將autofocus
設置爲true
即可。
Widget _buildTextField(){
return TextField(
autofocus: true,
);
}
改變鍵盤右下角的功能鍵
Widget _buildTextField(){
return TextField(
autofocus: true,
keyboardType: TextInputType.text,
// 右下角按鈕變爲:前往或者Go
textInputAction:TextInputAction.go,
);
}
改變鍵盤的輸入類型
Widget _buildTextField(){
return TextField(
autofocus: true,
keyboardType: TextInputType.number,
// 將鍵盤顯示類型設置爲數字鍵盤
keyboardType: TextInputType.number,
);
}
如何自適應屏幕彈起
目前來看TextField
已滿足一個輸入框的功能了。
但是它太醜了,這不符合Flutter
構建一個漂亮App
的目標
美化 TextField 樣式
主要是使用TextField
自帶的字段修改,或者使用InputDecoration
修改樣式。
TextField
的常用字段我們在上面已經給出註釋了,接下來查看InputDecoration
的常見字段:
字段基本釋義來源:Flutter文本輸入框TextField屬性(InputDecoration、textInputAction、inputFormatters等等)詳解
const InputDecoration({
this.icon, //位於裝飾器外部和輸入框前面的圖片
this.labelText,//用於描述輸入框,當輸入框獲取焦點時默認會浮動到上方,
this.labelStyle,// 控制labelText的樣式
this.helperText,//輔助文本,位於輸入框下方,如果errorText不爲空的話,則helperText不會顯示
this.helperStyle,//helperText的樣式
this.helperMaxLines,//提示信息最大行數
this.hintText,//提示文本,位於輸入框內部
this.hintStyle,//hintText的樣式
this.hintMaxLines,//提示信息最大行數
this.errorText,//errorText的信息
this.errorStyle,//errorText的樣式
this.errorMaxLines, //errorText的最大行數
this.hasFloatingPlaceholder = true, //labelText是否浮動,默認爲true
this.isDense,//改變輸入框是否爲密集型
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.focusColor,//輸入框有焦點時的邊框顏色
this.hoverColor,//輸入框被懸浮時的邊框顏色
this.errorBorder,//errorText不爲空,輸入框沒有焦點時要顯示的邊框
this.focusedBorder,//輸入框有焦點時的邊框
this.focusedErrorBorder,//errorText不爲空時,輸入框有焦點時的邊框
this.disabledBorder,//輸入框禁用時顯示的邊框
this.enabledBorder,//輸入框可用時顯示的邊框
this.border,//正常情況下的border
this.enabled = true,//輸入框是否可用
this.semanticCounterText,
this.alignLabelWithHint,
})
接下來我們通過幾個例子來看看實現的效果圖。
遊標顏色、粗細,控制輸入長度
Widget _buildTextField(){
return TextField(
autofocus: true,
cursorColor: Colors.deepOrange,
cursorRadius: Radius.circular(20.0),
cursorWidth: 10.0,
maxLength: 10,
);
}
密碼框
增加obscureText: true,
屬性即可實現輸入的內容是隱藏的。
改變下劃線顏色
默認下劃線是跟隨主題的紅色,這裏將其改爲橘色700。
Widget _buildTextField(){
return Container(
child: TextField(
autofocus: true,
decoration: InputDecoration(
border: InputBorder.none //隱藏下劃線
)
),
decoration: BoxDecoration(
// 下滑線橘色700,寬度3像素
border: Border(bottom: BorderSide(color: Colors.orange[700], width: 3.0))
),
);
}
圓角輸入框
Widget _buildTextField(){
return TextField(
autofocus: true,
cursorColor: Colors.deepOrange,
cursorRadius: Radius.circular(20.0),
cursorWidth: 10.0,
maxLength: 10,
obscureText: true,
decoration: InputDecoration(
// 文本內容的內邊距
contentPadding: EdgeInsets.all(10.0),
// 圓角矩形的輸入框樣式
border: OutlineInputBorder(
// 圓角半徑 10
borderRadius: BorderRadius.circular(10.0),
)),
);
}
帶有圖標輸入框
使用InputDecoration
常見的一些屬性完成了以下的效果圖:
Widget _buildTextField(){
return Column(
children: <Widget>[
TextField(
decoration: InputDecoration(
icon: Icon(Icons.supervised_user_circle),
suffixIcon: Icon(Icons.search),
prefixText: 'prefixText ',
suffixText: 'suffixText',
labelText: "用戶名",
helperText: '請輸入用戶名、手機號',
hintText: "用戶名或手機號",
prefixIcon: Icon(Icons.person)
),
),
TextField(
decoration: InputDecoration(
prefixIcon: Icon(Icons.lock),
suffixIcon: Icon(Icons.remove_red_eye),
labelText: "密碼",
hintText: "您的登錄密碼",
hintStyle: TextStyle(color: Colors.grey, fontSize: 13.0)
),
obscureText: true,
)
],
);
}
表單 Form 驗證
Flutter
提供了一個Form
組件,它可以對輸入框進行分組。Form
對應的狀態類爲FormState
,可以通過Form.of()
或GlobalKey
獲得。獲得狀態類之後就可以做統一操作了如:
FormState.validate()
:調用此方法後,會調用子孫FormField
的validate
回調,如果有一個校驗失敗,則返回false
,所有校驗失敗項都會返回用戶返回的錯誤提示。FormState.save()
:調用此方法後,會調用子孫FormField
的save
回調,用於保存表單內容FormState.reset()
:調用此方法後,會將子孫FormField
的內容清空。
輸入框內容校驗
- 自動校驗
autovalidate: true, //開啓自動校驗
,在 Form
組件下設置該屬性爲true
- 手動校驗
通過點擊按鈕來校驗Form
中所有TextField
的信息。
- 定義全局的
key
,用於獲取state
- 在
TextField
中做驗證判斷 - 點擊按鈕時獲取
FormState
,調用validate()
方法。
由於代碼過多,粘貼閱讀體驗不好,相關代碼可參考:dongxi346/Flutter-WanAndroid
輸入框內容重置
- 通過
FormState
去調用
var _formState = _formKey.currentState as FormState;
// Form 裏面的所有TextField輸入框內容都被清空
_formState.reset();
由於代碼過多,粘貼閱讀體驗不好,相關代碼可參考:dongxi346/Flutter-WanAndroid
輸入內容保存
- 在
TextField
中使用onSave
字段
例如:
onSaved: (value){
_passWord = value;
},
- 通過
FormState
去調用
var _formState = _formKey.currentState as FormState;
// Form 裏面的所有TextField onSave 方法都被調用
_formState.save();
由於代碼過多,粘貼閱讀體驗不好,相關代碼可參考:dongxi346/Flutter-WanAndroid
登錄頁面例子
原來的效果圖來源忘記了,好像是在一個第三方庫中出現的效果,當時覺得UI
超級好看就直接複製了作者的源碼在 現有的項目 Flutter-WanAndroid-login-page 中使用 ,如有侵權聯繫。
通過前面幾篇文章以及本篇文章的分析,實現這個登錄效果圖應該是相當容易了。
這裏暫不實現,待後面學習了佈局的擺放後再來實現這個例子。