一、Row:横向水平布局
Row的属性列表如下:
Row({
Key key,
MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,
MainAxisSize mainAxisSize = MainAxisSize.max,
CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center,
TextDirection textDirection,
VerticalDirection verticalDirection = VerticalDirection.down,
TextBaseline textBaseline,
List<Widget> children = const <Widget>[],
})
可以看如下示例,
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp (
title: 'Row Widget Demo',
home: Scaffold(
appBar: new AppBar(
title: new Text('水平方向布局'),
),
body: new Row(
children: <Widget>[
new RaisedButton(
onPressed: (){},
color: Colors.orange,
child: new Text('Orange Button'),
),
Expanded(child: new RaisedButton( /*
expanded:扩充的,填满的。是一个组件。
如果不使用这个组件,那么Row就会根据button原始大小填充,如果使用expanded,它就会填充满。
如果这些子元素都使用expanded元素,那么这三个按钮会均匀分布填满整个屏幕。
如果前后两个都使用的灵活布局中间使用expended的话,那么中间这个按钮会把剩下的空间都填充满。
*/
onPressed: (){},
color: Colors.red,
child: new Text('Red Button'),
), ),
new RaisedButton(
onPressed: (){},
color: Colors.yellow,
child: new Text('Yellow Button'),
),
],
),
),
);
}
}
运行结果如下:
二、Column:纵向水平布局
Column的属性列表如下:
Column({
Key key,
MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,
MainAxisSize mainAxisSize = MainAxisSize.max,
CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center,
TextDirection textDirection,
VerticalDirection verticalDirection = VerticalDirection.down,
TextBaseline textBaseline,
List<Widget> children = const <Widget>[],
}) : super(
children: children,
key: key,
direction: Axis.vertical,
mainAxisAlignment: mainAxisAlignment,
mainAxisSize: mainAxisSize,
crossAxisAlignment: crossAxisAlignment,
textDirection: textDirection,
verticalDirection: verticalDirection,
textBaseline: textBaseline,
);
示例如下:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp (
title: 'Row Widget Demo',
home: Scaffold(
appBar: new AppBar(
title: new Text('垂直方向布局'),
),
body: new Column(
crossAxisAlignment: CrossAxisAlignment.center, //对齐属性,根据最长的内容进行对齐,而不是针对整个屏幕
mainAxisAlignment: MainAxisAlignment.center , //主轴方向对齐,由于现在是column组件,所以垂直方向是主轴,crossAxis是水平
children: <Widget>[
Text('I am cat'),
Text('My name is Amy'),
Text('I like cat'),
Text('I like dog'),
],
),
),
);
}
}
运行结果如下:
由此我们可以看见这个布局主要是针对Column,如果想要针对整个屏幕居中,需要对整个column进行居中设置,核心代码块如下:
body: Center( //对整个Column进行剧中设置
child: Column(
crossAxisAlignment: CrossAxisAlignment.center, //对齐属性,根据最长的内容进行对齐,而不是针对整个屏幕
mainAxisAlignment: MainAxisAlignment.center , //主轴方向对齐,由于现在是column组件,所以垂直方向是主轴,crossAxis是水平
children: <Widget>[
Text('I am cat'),
Text('My name is Amy'),
Text('I like cat'),
Text('I like dog'),
],
),
),
运行结果如下:
在实际开发过程中,如果需要头部和底部文本固定,中间的部分任意使用。可以使用Expended组件来实现。核心代码块如下:
body: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center, //对齐属性,根据最长的内容进行对齐,而不是针对整个屏幕
mainAxisAlignment: MainAxisAlignment.center , //主轴方向对齐,由于现在是column组件,所以垂直方向是主轴,crossAxis是水平
children: <Widget>[
Text('I am cat'),
Expanded(child: Text('My name is Amy')),
Text('I like cat'),
Text('I like eat'),
],
),
),
PS:主轴和副轴的区分
在设置对齐方式的时候你会发现右mainAxisAlignment属性,意思就是主轴对齐方式,那什么是主轴,什么又是幅轴那。
main轴:如果你用column组件,那垂直就是主轴,如果你用Row组件,那水平就是主轴。
cross轴:cross轴我们称为幅轴,是和主轴垂直的方向。比如Row组件,那垂直就是幅轴,Column组件的幅轴就是水平方向的。
主轴和幅轴我们搞清楚,才能在实际工作中随心所欲的进行布局。
比如现在我们要把上面的代码,改成垂直方向居中。因为用的是Column组件,所以就是主轴方向,这时候你要用的就是主轴对齐了。
三、Stack:层叠布局
Stack:层叠布局。层叠顾名思义需要两个以上的组件才能进行。
Stack的属性列表如下:
Stack({
Key key,
this.alignment = AlignmentDirectional.topStart,
this.textDirection,
this.fit = StackFit.loose,
this.overflow = Overflow.clip,
List<Widget> children = const <Widget>[],
})
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
//定义一个Stack组件,再放入到Body中
var stack = new Stack(
children: <Widget>[
new CircleAvatar( //圆形头像
backgroundImage: new NetworkImage('https://aod-image-material.cdn.bcebos.com/5/pic/610fdd209d7aa5d5e0d909f0af85d0e4.jpg'),
radius: 100.0,
),
new Container(
decoration: new BoxDecoration(
color: Colors.lightBlue,
),
padding: EdgeInsets.all(5.0),
child: Text('A Beauty'),
)
],
);
return MaterialApp (
title: 'Row Widget Demo',
home: Scaffold(
appBar: new AppBar(
title: new Text('层叠布局'),
),
body: Center(
child: stack,
),
),
);
}
}
运行结果如下:
如果想要修改两个组件之间的位置,需要在Stack中修改alignment对齐属性, alignment: const FractionalOffset(0.5, 0.95),组件的对齐方式,x轴和y轴的的数值设置都是0~1之间,如果不设置的话文本组件会和头像组件基于左上角对齐。
修改之后的代码块如下:
var stack = new Stack(
//组件的对齐方式,x轴和y轴的的数值设置都是0~1之间,如果不设置的话文本组件会和头像组件基于左上角对齐
alignment: const FractionalOffset(0.5, 0.95),
children: <Widget>[
new CircleAvatar( //圆形头像
backgroundImage: new NetworkImage('https://aod-image-material.cdn.bcebos.com/5/pic/610fdd209d7aa5d5e0d909f0af85d0e4.jpg'),
radius: 100.0,
),
new Container(
decoration: new BoxDecoration(
color: Colors.lightBlue,
),
padding: EdgeInsets.all(5.0),
child: Text('A Beauty'),
),
],
);
修改之后的运行结果:
Positioned属性
上面示例是两个组件之间的层叠布局,如果是三个组件布局该怎么办呢?
这个时候需要使用Positioned组件来修改组件之间的位置。
const Positioned({
Key key,
this.left,
this.top,
this.right,
this.bottom,
this.width,
this.height,
@required Widget child,
})
代码示例如下:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
//定义一个Stack组件,再放入到Body中
var stack = new Stack(
//组件的对齐方式,x轴和y轴的的数值设置都是0~1之间,如果不设置的话文本组件会和头像组件基于左上角对齐
alignment: const FractionalOffset(0.5, 0.95),
children: <Widget>[
new CircleAvatar( //圆形头像
backgroundImage: new NetworkImage('https://aod-image-material.cdn.bcebos.com/5/pic/610fdd209d7aa5d5e0d909f0af85d0e4.jpg'),
radius: 100.0,
),
new Positioned(
top: 10.0,
left: 60.0,
child: new Text('A Beauty',
style: TextStyle(
fontSize: 25,
color: Colors.red,
backgroundColor: Colors.lightBlue,
),),
),
new Positioned(
bottom: 10.0,
right: 40.0,
child: new Text('18 years',
style: TextStyle(
fontSize: 30,
color: Colors.yellow,
backgroundColor: Colors.lightBlue,
),),
),
],
);
运行结果如下:
四、Card:卡片布局
卡片布局的属性列表如下:
const Card({
Key key,
this.color,
this.elevation,
this.shape,
this.borderOnForeground = true,
this.margin,
this.clipBehavior,
this.child,
this.semanticContainer = true,
})
示例代码:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
var card = new Card(
child: Column(
children: <Widget>[
ListTile(
title: Text('Amy', style: TextStyle(fontWeight: FontWeight.w400),),
subtitle: Text('18 years'),
leading: new Icon(Icons.account_box,color: Colors.lightBlue,),
),
new Divider(),//添加分割线
ListTile(
title: Text('Bob', style: TextStyle(fontWeight: FontWeight.w400),),
subtitle: Text('20 years'),
leading: new Icon(Icons.account_box,color: Colors.lightBlue,),
),
new Divider(),//添加分割线
ListTile(
title: Text('Cola', style: TextStyle(fontWeight: FontWeight.w400),),
subtitle: Text('10 years'),
leading: new Icon(Icons.account_box,color: Colors.lightBlue,),
)
],
),
);
return MaterialApp (
title: 'Row Widget Demo',
home: Scaffold(
appBar: new AppBar(
title: new Text('层叠布局'),
),
body: Center(
child: card,
),
),
);
}
}
运行结果如下: