Flutter常用基本布局Layout(2)
在上文中我们主要介绍了Row和Column的用法,借助于这两个Widget我们可以很方便的完成我们想要的界面效果,根据前面学过的内容完成如下布局效果:
实现如上效果的代码如下:
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("layout"),
),
body: new Column(
children: <Widget>[
new Container(
padding: const EdgeInsets.all(10.0),
decoration: new BoxDecoration(
border: new Border(
bottom: new BorderSide(
color: Colors.grey,
)),
),
child: new Row(children: <Widget>[
new Icon(
Icons.chat,
color: Colors.lightBlueAccent,
),
new Expanded(
child: new Text(
"消息",
textAlign: TextAlign.right,
),
)
]),
),
new Container(
padding: const EdgeInsets.all(10.0),
decoration: new BoxDecoration(
border: new Border(
bottom: new BorderSide(
color: Colors.grey,
)),
),
child: new Row(children: <Widget>[
new Icon(
Icons.stars,
color: Colors.lightBlueAccent,
),
new Expanded(
child: new Text(
"收藏",
textAlign: TextAlign.right,
),
)
]),
),
new Container(
padding: const EdgeInsets.all(10.0),
decoration: new BoxDecoration(
border: new Border(
bottom: new BorderSide(
color: Colors.grey,
)),
),
child: new Row(children: <Widget>[
new Icon(
Icons.lock,
color: Colors.lightBlueAccent,
),
new Expanded(
child: new Text(
"账户",
textAlign: TextAlign.right,
),
)
]),
),
new Container(
padding: const EdgeInsets.all(10.0),
decoration: new BoxDecoration(
border: new Border(
bottom: new BorderSide(
color: Colors.grey,
)),
),
child: new Row(children: <Widget>[
new Icon(
Icons.send,
color: Colors.lightBlueAccent,
),
new Expanded(
child: new Text(
"反馈",
textAlign: TextAlign.right,
),
)
]),
),
new Container(
padding: const EdgeInsets.all(10.0),
decoration: new BoxDecoration(
border: new Border(
bottom: new BorderSide(
color: Colors.grey,
)),
),
child: new Row(children: <Widget>[
new Icon(
Icons.settings,
color: Colors.lightBlueAccent,
),
new Expanded(
child: new Text(
"设置",
textAlign: TextAlign.right,
),
)
]),
),
],
),
);
}
}
不难看出效果和布局也是很简单,但是认真的朋友会发现代码基本算是冗杂的算是重复了五次,所以我们为了取消这样代码长度,和复用性的问题,我们把他拆出来(只拆1个就好)
新建一个class,你想在别的dart文件里建也可以。
class MyItem extends StatefulWidget {
IconData myIcon;
String text;
MyItem({Key key,this.myIcon,this.text}) : super(key:key);
@override
_MyItemState createState() => _MyItemState();
}
class _MyItemState extends State<MyItem> {
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.all(10.0),
decoration: new BoxDecoration(
border: new Border(
bottom: new BorderSide(
color: Colors.grey,
)),
),
child: new Row(children: <Widget>[
new Icon(
widget.myIcon,
color: Colors.lightBlueAccent,
),
new Expanded(
child: new Text(
widget.text,
textAlign: TextAlign.right,
),
)
]),
);
}
}
这就是我们的MyItem类,里面定义了两个参数,我们可以传参,这样代码可以简单点。
在前面的修改变为:
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("layout"),
),
body: new Column(
children: <Widget>[
MyItem(myIcon: Icons.chat,text: '消息'),
MyItem(myIcon: Icons.stars,text: '收藏'),
MyItem(myIcon: Icons.lock,text: '账户'),
MyItem(myIcon: Icons.send,text: '反馈'),
MyItem(myIcon: Icons.send,text: '设置'),
],
),
);
}
}
这样一来,我们每增加一行只需要在增加一个MyListItem对象即可。
好了,说完了Row和Column的用法,还有Table、Stack和IndexedStack,他们也都是Layout,也是有多个Widget组成。我们就简要的说一下。
Table
Table可以制作表格。
看看Table的签名函数即构造方法:
Table({
Key key,
this.children: const <TableRow>[],
this.columnWidths,//列宽
this.defaultColumnWidth: const FlexColumnWidth(1.0),
this.textDirection,//文字方向
this.border,//边框
this.defaultVerticalAlignment: TableCellVerticalAlignment.top,//对齐方式
this.textBaseline//基线
})
不多说了,构造函数就是这样,
我们的实现效果是:
实现代码为:
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Stack"),
),
body: new Table(
children: <TableRow>[
new TableRow(children: <Widget>[
new Text(
"姓名",
textAlign: TextAlign.center,
),
new Text("职位", textAlign: TextAlign.center)
]),
new TableRow(children: <Widget>[
new Text("flyou", textAlign: TextAlign.center),
new Text("终端开发工程师", textAlign: TextAlign.center)
]),
new TableRow(children: <Widget>[
new Text("张三", textAlign: TextAlign.center),
new Text("Java开发工程师", textAlign: TextAlign.center)
]),
new TableRow(children: <Widget>[
new Text("李四", textAlign: TextAlign.center),
new Text("大数据开发工程师", textAlign: TextAlign.center)
]),
new TableRow(children: <Widget>[
new Text("王五", textAlign: TextAlign.center),
new Text("Python数据工程师", textAlign: TextAlign.center)
])
],
),
);
}
}
可以看到,上面的数据就按照行和列显示了。有强迫症的人就可以用border给加上边线了(和Container的border使用时一样的)。border: new TableBorder.all(color: Colors.grey),
效果就不演示了。
Stack
类似于我们重叠布局就是设置了在空间的位置,然后放我们的空间!可以重叠!
return new Scaffold(
appBar: new AppBar(
title: new Text(“Stack”),
),
body: new Stack(
children: <Widget>[
new Icon(
Icons.check_circle,
size: 100.0,
color: Colors.yellow,
),
new Icon(Icons.check_circle, color: Colors.lightGreen,)
],
alignment: Alignment.bottomRight,
),
);
}
}
代码如下:
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Stack"),
),
body: new Stack(
children: <Widget>[
new Icon(
Icons.check_circle,
size: 100.0,
color: Colors.yellow,
),
new Icon(Icons.check_circle, color: Colors.lightGreen,)
],
alignment: Alignment.bottomRight,
),
);
}
}
IndexedStack
在上面我们说明了Stack,基本上知道了Stack的用法,其实IndexedStack的用法和Stack一样,只不过IndexedStack只显示指定位置的Widget,其他的位置的Widget不会显示。
看代码:
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Stack"),
),
body:new IndexedStack(
index: 1,
children: <Widget>[
new Icon(
Icons.check_circle,
size: 100.0,
color: Colors.green,
),
new Icon(
Icons.error_outline,
size: 100.0,
color: Colors.red,
)
],
alignment: Alignment.bottomRight,
),
);
}
}
效果如下:
从上面代码可以看出来,我们定义了两个Icon,第一个是一个绿色的对号,第二个是一个红色的感叹号,仅仅比上面的Stack多了一个index为1(默认为0)参数。
要实现第一个Icon,我们只需要把index换为0,或者不写就好(默认为0)。
其实这个IndexedStack还是很有用的,比如说你的应用现实的额多个状态(加载中、加载完成、网络错误)可以使用这个组件来很好的完成控制。而不是我们用bool值进行判断( bool : 1 ? 2)