前言
在上一篇中,我們瞭解了常用的Widget
,這一篇,我們從實際案例出發,來深入學習下Widget
。
案例1 模擬登陸
先看效果圖
- 1.我們需要2個輸入框,1個按鈕
這裡用到的都是之前說過的
Widget
,就直接貼程式碼了,建議先看這篇【Flutter】開發之基礎Widget(二)
class LoginDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('LoginDemo'),
),
body: Container(
margin: EdgeInsets.all(15),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 100),
),
TextField(
decoration: InputDecoration(
hintText: '請輸入賬戶',
hintStyle: TextStyle(color: Colors.black45),
contentPadding: EdgeInsets.all(10),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(4),
)),
),
Padding(
padding: EdgeInsets.only(top: 15),
),
TextField(
//顯示*號
obscureText: true,
decoration: InputDecoration(
hintText: '請輸入密碼',
hintStyle: TextStyle(color: Colors.black45),
contentPadding: EdgeInsets.all(10),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(4),
)),
),
Padding(
padding: EdgeInsets.only(top: 50),
),
FlatButton(
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(10)),
child: Container(
height: 50,
width: 300,
decoration: BoxDecoration(color: Colors.deepOrangeAccent),
alignment: AlignmentDirectional.center,
child: Text(
'登入',
style: TextStyle(
fontSize: 18,
color: Colors.white,
backgroundColor: Colors.deepOrangeAccent,
),
),
),
),
)
],
),
),
);
}
}
複製程式碼
- 2.需要獲取輸入的內容
這裡有2個方法
1). 處理 onChanged
回撥
TextField(
//文字改變時呼叫
onChanged: (String content) {
print("content=" + content);
}
複製程式碼
2). 提供一個TextEditingController
TextEditingController user = new TextEditingController();
TextField(
...省略...
controller: user ,
...省略...
)
複製程式碼
然後通過user.text
方法即可取得輸入內容。
- 3.點選事件
1).可以通過onPressed
實現
FlatButton(
onPressed: () {
//顯示彈窗
_showDialog(context);
})
複製程式碼
注:Flutter
的語法是 Dart
,Dart
不像 Java
,沒有關鍵詞 public
、private
等修飾符,_
下橫線代表 private
,但是有 @protected
註解。
然後,我們需要判斷密碼是否大於6位,如不是,彈窗提示
void _showDialog(BuildContext context) {
if (pwd.text.length < 6) {
showDialog(
context: context,
builder: (BuildContext content) {
return AlertDialog(
title: Text("提示"),
content: Text('輸入的密碼不能小於6位'),
);
},
);
}
}
複製程式碼
正常的邏輯來說,彈出窗中應該有按鈕,點選重新輸入,但是卻發現,有的Widget
沒有點選事件,這時,我們可以通過在外面巢狀GestureDetector
來處理,GestureDetector
還有更多的功能,這個我們後面再說
2).巢狀GestureDetector
void _showDialog(BuildContext context) {
if (pwd.text.length < 6) {
showDialog(
context: context,
builder: (BuildContext content) {
return AlertDialog(
title: Text("提示"),
content: Text('輸入的密碼不能小於6位'),
actions: <Widget>[
GestureDetector(
child: Container(
child: Text('重新輸入'),
),
onTap: () {
pwd.clear();
//關閉彈窗
Navigator.of(context).pop();
},
),
],
);
},
);
}
}
複製程式碼
案例2 Table 頁
先看效果圖
- 1.
TabBar
上半部分使用的是AppBar
+TabBar
,詳細程式碼如下:
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('TableDemo'),
bottom: TabBar(
//可以滑動
isScrollable: true,
//邊距
labelPadding: EdgeInsets.only(right: 0),
//顏色
labelColor: Colors.orangeAccent,
//樣式 選中的
labelStyle: TextStyle(fontSize: 18),
//點選事件
onTap: (index) {
},
//未選中的顏色
unselectedLabelColor: Colors.pink,
//未選中樣式
unselectedLabelStyle: TextStyle(fontSize: 14),
//指示器的寬度
indicatorSize: TabBarIndicatorSize.tab,
//指示器顏色
indicatorColor: Colors.amber,
//指示器高度
indicatorWeight: 2,
tabs: <Widget>[
Container(
width: 100,
height: 40,
child: Center(
child: Text('MODEL 1'),
),
),
Container(
width: 100,
height: 40,
child: Center(
child: Text('MODEL 2'),
),
),
Container(
width: 100,
height: 40,
child: Center(
child: Text('MODEL 3'),
),
),
],
),
),
}
複製程式碼
- 2.
PageView
用法類似於ListView
PageView.builder
PageView.custom
PageView.builder(
itemBuilder: (BuildContext context, int index) {
return Container(
child: Center(
child: Text('PAGE ${index}'),
),
);
},
itemCount: 5,
onPageChanged: (indext) {},
),
複製程式碼
方便起見,我們這裡使用的是children
Widget _pageView() {
return PageView(
children: <Widget>[
Container(
color: Colors.blue,
alignment: AlignmentDirectional.center,
child: Text('PAGE 1'),
),
Container(
color: Colors.deepPurpleAccent,
alignment: AlignmentDirectional.center,
child: Text('PAGE 2'),
),
Container(
color: Colors.lightGreen,
alignment: AlignmentDirectional.center,
child: Text('PAGE 3'),
),
],
onPageChanged: (index) {
},
);
}
複製程式碼
- 3.
TabBar
和PageView
聯動
PageView
的控制使用的是PageController
1).初始化
PageController pageController = new PageController();
2).在PageView
中宣告
PageView(
...省略...
controller: pageController,
...省略...
)
複製程式碼
3).在TabBar
中使用
TabBar(
...省略...
//點選事件
onTap: (index) {
pageController.jumpToPage(index);
},
...省略...
)
複製程式碼
TabBar
的控制使用的是TabController
需要注意
我們的父級Widget
必須是繼承StatefulWidget
;需要實現SingleTickerProviderStateMixin
1).初始化
class TableDemo extends StatefulWidget {
@override
_TableDemoState createState() => _TableDemoState();
}
class _TableDemoState extends State<TableDemo>
with SingleTickerProviderStateMixin {
TabController _tabController;
@override
void initState() {
super.initState();
///初始化時建立控制器
///通過 with SingleTickerProviderStateMixin 實現動畫效果。
_tabController = new TabController(vsync: this, length: 3);
}
@override
void dispose() {
///頁面銷燬時,銷燬控制器
_tabController.dispose();
super.dispose();
}
}
複製程式碼
2).在TabBar
中宣告
TabBar(
...省略...
controller: _tabController,
...省略...
)
複製程式碼
3).在PageView
中使用
PageView(
...省略...
onPageChanged: (index) {
_tabController.animateTo(index);
},
...省略...
)
複製程式碼
- 4.擴充套件 底部Table
可以使用
Scaffold
的bottomNavigationBar
屬性
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('TableDemo'),
),
body: _pageView(),
bottomNavigationBar: Container(
height: 40,
child: Center(
child: _tabView(),
),
),
);
}
複製程式碼