17.表單
class FormTestRoute extends StatefulWidget {
@override
_FormTestRouteState createState() => new _FormTestRouteState();
}
class _FormTestRouteState extends State<FormTestRoute> {
//文本框的控制器,通過它可以設置/獲取編輯框的內容、選擇編輯內容、監聽編輯文本改變事件
TextEditingController _unameController = new TextEditingController();
TextEditingController _pwdController = new TextEditingController();
//用來獲取FormState
GlobalKey _formKey= new GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title:Text("Form Test"),
),
body: Padding(
//設置水平和垂直方向的間距(空白部分)
padding: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 24.0),
//表單組件
child: Form(
key: _formKey, //設置globalKey,用於後面獲取FormState
autovalidate: true, //開啓自動校驗
child: Column(
children: <Widget>[
//表單中的文本框
TextFormField(
//自動聚焦
autofocus: true,
//設置控制器
controller: _unameController,
decoration: InputDecoration(
//設置標籤文本
labelText: "用戶名",
//設置提示文本
hintText: "用戶名或郵箱",
//設置圖標
icon: Icon(Icons.person)
),
// 校驗用戶名
validator: (v) {
return v
.trim()
.length > 0 ? null : "用戶名不能爲空";
}
),
TextFormField(
controller: _pwdController,
decoration: InputDecoration(
labelText: "密碼",
hintText: "您的登錄密碼",
icon: Icon(Icons.lock)
),
//隱藏文本
obscureText: true,
//校驗密碼
validator: (v) {
return v
.trim()
.length > 5 ? null : "密碼不能少於6位";
}
),
// 登錄按鈕
Padding(
padding: const EdgeInsets.only(top: 28.0),
child: Row(
children: <Widget>[
Expanded(
child: RaisedButton(
padding: EdgeInsets.all(15.0),
child: Text("登錄"),
color: Colors.red,
textColor: Colors.white,
onPressed: () {
// 通過_formKey.currentState 獲取FormState後,
// 調用validate()方法校驗用戶名密碼是否合法,校驗
// 通過後再提交數據。
if((_formKey.currentState as FormState).validate()){
//驗證通過提交數據
}
},
),
),
],
),
)
],
),
),
),
);
}
}
效果:
18.線性進度條
// 線性進度條高度指定爲3
SizedBox(
height: 3,
child: LinearProgressIndicator(
backgroundColor: Colors.grey[200],
valueColor: AlwaysStoppedAnimation(Colors.blue),
value: .5,
),
),
效果:
19.線性佈局
Column(
//測試Row對齊方式,排除Column默認居中對齊的干擾
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
//Row組件內居中對齊
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(" hello world "),
Text(" I am Jack "),
],
),
Row(
mainAxisSize: MainAxisSize.min,
//如果mainAxisSize值爲MainAxisSize.min,則此屬性無意義
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(" hello world "),
Text(" I am Jack "),
],
),
Row(
//Row組件內左對齊
mainAxisAlignment: MainAxisAlignment.end,
//Text文本由右到左顯示
textDirection: TextDirection.rtl,
children: <Widget>[
Text(" hello world "),
Text(" I am Jack "),
],
),
Row(
//Row組件內底對齊
crossAxisAlignment: CrossAxisAlignment.start,
//從低向頂排列
verticalDirection: VerticalDirection.up,
children: <Widget>[
Text(" hello world ", style: TextStyle(fontSize: 30.0),),
Text(" I am Jack "),
],
),
],
),
效果:
20.彈性佈局
class FlexLayoutTestRoute extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
//Flex的兩個子widget按1:2來佔據水平空間
Flex(
//佔據水平空間
direction: Axis.horizontal,
children: <Widget>[
//佔比爲1的空間塊
Expanded(
flex: 1,
child: Container(
//這裏面的height是正常的
height: 30.0,
color: Colors.red,
),
),
//佔比爲2的空間塊
Expanded(
flex: 2,
child: Container(
height: 30.0,
color: Colors.green,
),
),
],
),
Padding(
padding: const EdgeInsets.only(top: 20.0),
child: SizedBox(
//設置總高度爲100
height: 100.0,
//Flex的三個子widget,在垂直方向按2:1:1來佔用100像素的空間
child: Flex(
//佔據垂直空間
direction: Axis.vertical,
children: <Widget>[
//佔據總高度的1/2
Expanded(
flex: 2,
child: Container(
//這裏面的height是不起作用的,以佔比爲主
height: 15.0,
color: Colors.red,
),
),
//佔據總高度的1/4
Spacer(
flex: 1,
),
//佔據總高度的1/4
Expanded(
flex: 1,
child: Container(
//這裏面的height是不起作用的,以佔比爲主
height: 30.0,
color: Colors.green,
),
),
],
),
),
),
],
);
}
}
效果: