前言
在上一篇中,我们了解了常用的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
1).PageView.builder
2).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(),
),
),
);
}