上一篇文章中我們一起學習了什么是Text跟如何給Text設置字體樣式以及Text Widget的一些常用屬性Flutter入門進階之旅(三) Text Widgets,通過對Text的學習我們了解到Text是用于顯示文本的,如果對顯示的文本有一些特殊的要求,比如字體樣式突那,文字顏色我們可以通過TextStyle去給Text指定style來做個性化定制,這一點跟原生Android的TextView非常類似,有了文字顯示就肯定會有文字輸入峰搪,今天我們就一起來學習一下Flutter中的文字輸入Widget TextField。
先來看下TextField的構造方法
const TextField({
Key key,
this.controller, ////控制器庵楷,控制TextField文字
this.focusNode,
this.decoration = const InputDecoration(), //輸入器裝飾
TextInputType keyboardType, ////輸入的類型
this.textInputAction,
this.textCapitalization = TextCapitalization.none,
this.style,
this.textAlign = TextAlign.start, //文字顯示位置
this.autofocus = false,
this.obscureText = false,
this.autocorrect = true,
this.maxLines = 1,
this.maxLength,
this.maxLengthEnforced = true,
this.onChanged, //文字改變觸發(fā)
this.onEditingComplete, //當用戶提交可編輯內(nèi)容時調(diào)用
this.onSubmitted, ////文字提交觸發(fā)(鍵盤按鍵)
this.inputFormatters,
this.enabled,
this.cursorWidth = 2.0,
this.cursorRadius,
this.cursorColor,
this.keyboardAppearance,
this.scrollPadding = const EdgeInsets.all(20.0),
})
通過上面的構造方法跟預覽效果圖罢艾,熟悉android開發(fā)的小伙伴們是不是有種似曾相識的感覺,F(xiàn)lutter的TextField跟原生Android中的EditText用法包括部分屬性名幾乎都是一樣的尽纽,比如我們可以通過keyboardType來指定喚起軟件盤時的輸入方式咐蚯,例如上圖的兩個輸入框屬性設置:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() {
runApp(new MaterialApp(home: new PullToRefreshDemo()));
}
class PullToRefreshDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: new AppBar(
title: new Text("文本輸入"),
),
body: new Center(
child: new Column(
children: <Widget>[
new Text("簡單文本輸入框",style: new TextStyle(fontSize: 20.0)),
new TextField(keyboardType: TextInputType.text,), //指定輸入方式為文本輸入
new TextField(keyboardType: TextInputType.number,),//指定喚起軟鍵盤時默認顯示數(shù)字鍵盤
],
)),
);
}
}
通過上面的構造方法我們留意到TextField給我提供了onChanged、onSubmitted弄贿、OnEditingComplete回調(diào)方法幫助我們監(jiān)聽輸入框的內(nèi)容變化春锋、編輯提交、編輯完成等事件差凹,我們給輸入框綁定上述監(jiān)聽方法做下測試:
new TextField(
onSubmitted: (value){
print("------------文字提交觸發(fā)(鍵盤按鍵)--");
},
onEditingComplete: (){
print("----------------編輯完成---");
},
onChanged: (value){
print("----------------輸入框中內(nèi)容為:$value--");
},
keyboardType: TextInputType.text,
),
喚起軟鍵盤后在輸入框中輸入123456期奔,log控制臺打印出:
到此對輸入框的基本使用你已經(jīng)完全get到了,但是現(xiàn)實開發(fā)過程中危尿,可能我們會需要給輸入框指定一些輔助性的說明內(nèi)容呐萌,比如輸入框未輸入內(nèi)容時添加hint提示,或者在輸入框的旁邊添加Icon指示谊娇,或者輸入框內(nèi)部文字的顯示樣式肺孤、背景色等等,這些輔助性的設置在Flutter中統(tǒng)一有一個叫做InputDecoration的裝飾器來完成操作,我們先來看下InputDecoration的構造方法赠堵,然后來簡單嘗試下幾個日常開發(fā)中常用的操作小渊。
const InputDecoration({
this.icon, //輸入框左側添加個圖標
this.labelText,//輸入框獲取焦點/有內(nèi)容 會移動到左上角,否則在輸入框內(nèi)labelTex的位置
this.labelStyle,
this.helperText,
this.helperStyle,
this.hintText, //未輸入文字時茫叭,輸入框中的提示文字
this.hintStyle,
this.errorText,
this.errorStyle,
this.errorMaxLines,
this.isDense,
this.contentPadding,
this.prefixIcon, //輸入框內(nèi)側左面的控件
this.prefix,
this.prefixText,
this.prefixStyle,
this.suffixIcon,//輸入框內(nèi)側右面的圖標
this.suffix,
this.suffixText,
this.suffixStyle,
this.counterText,
this.counterStyle,
this.filled,
this.fillColor,
this.errorBorder,
this.focusedBorder,
this.focusedErrorBorder,
this.disabledBorder,
this.enabledBorder,
this.border, //增加一個邊框
this.enabled = true,
this.semanticCounterText,
})
給輸入框添加輸入輔助性輸入說明:
body: new Center(
child: new TextField(
decoration: new InputDecoration(
labelText: "請輸入內(nèi)容",//輸入框內(nèi)無文字時提示內(nèi)容酬屉,有內(nèi)容時會自動浮在內(nèi)容上方
helperText: "隨便輸入文字或數(shù)字", //輸入框底部輔助性說明文字
prefixIcon: new Icon(Icons.print), //輸入框左邊圖標
suffixIcon: new Icon(Icons.picture_as_pdf), //輸入框右邊圖片
contentPadding: const EdgeInsets.only(bottom:15.0)),
keyboardType: TextInputType.number,
),
));
通過給InputDecoration設置border給輸入框添加邊框:
body: new Center(
child: new TextField(
decoration: new InputDecoration(
border: new OutlineInputBorder( //添加邊框
gapPadding: 10.0,
borderRadius: BorderRadius.circular(20.0),
),
prefixIcon: new Icon(Icons.print),
contentPadding: const EdgeInsets.all(15.0)),
keyboardType: TextInputType.number,
),
其他樣式跟屬性讀者可自行運行體驗,我就不逐一列舉說明了揍愁,總之參考文檔再結合原生開發(fā)的經(jīng)驗去使用TextField還是比較簡單的呐萨。下面我分享一個完整的登錄UI的例子供大家參考:
完整代碼:
import 'package:flutter/material.dart';
void main() {
runApp(new MaterialApp(home: new MyApp()));
}
class MyApp extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return new MyAppState();
}
}
class MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
TextEditingController _userPhoneController = new TextEditingController();
TextEditingController _userPasswordController = new TextEditingController();
/**
* 清空輸入框內(nèi)容
*/
void onTextClear() {
setState(() {
_userPhoneController.text = "";
_userPasswordController.text = "";
});
}
return new Scaffold(
appBar: new AppBar(
title: new Text("登錄"),
),
body: new Column(
children: <Widget>[
new TextField(
controller: _userPhoneController,
keyboardType: TextInputType.number,
decoration: new InputDecoration(
contentPadding: const EdgeInsets.all(10.0),
icon: new Icon(Icons.phone),
labelText: "請輸入手機號",
helperText: "注冊時填寫的手機號"),
onChanged: (String str) {
//onChanged是每次輸入框內(nèi)每次文字變更觸發(fā)的回調(diào)
print('手機號為:$str----------');
},
onSubmitted: (String str) {
//onSubmitted是用戶提交而觸發(fā)的回調(diào){當用戶點擊提交按鈕(輸入法回車鍵)}
print('最終手機號為:$str---------------');
},
),
new TextField(
controller: _userPasswordController,
keyboardType: TextInputType.text,
decoration: new InputDecoration(
contentPadding: const EdgeInsets.all(10.0),
icon: new Icon(Icons.nature_people),
labelText: "請輸入名字",
// hintText: "fdsfdss",
helperText: "注冊名字"),
),
new Builder(builder: (BuildContext context) {
return new RaisedButton(
onPressed: () {
if (_userPasswordController.text.toString() == "10086" &&
_userPhoneController.text.toString() == "10086") {
Scaffold.of(context)
.showSnackBar(new SnackBar(content: new Text("校驗通過")));
} else {
Scaffold.of(context)
.showSnackBar(new SnackBar(content: new Text("校驗有問題,請重新輸入")));
onTextClear(); //情況輸入內(nèi)容莽囤,讓用戶重新輸入
}
},
color: Colors.blue,
highlightColor: Colors.deepPurple,
disabledColor: Colors.cyan,
child: new Text(
"登錄",
style: new TextStyle(color: Colors.white),
),
);
})
],
));
}
}