Flutter拥有丰富的布局widget,但这里有一些最常用的布局widget。其目的是尽可能快地让您构建应用并运行,而不是让您淹没在整个完整的widget列表中。
以下widget分为两类:widgets library中的标准widget和Material Components library中的专用widget 。 任何应用程序都可以使用widgets library中的widget,但只有Material应用程序可以使用Material Components库。
许多布局会自由使用容器来使用padding分隔widget,或者添加边框(border)或边距(margin)。您可以通过将整个布局放入容器并更改其背景颜色或图片来更改设备的背景。
除了下面的例子之外,本教程中的许多示例都使用了Container。 您还可以在Flutter Gallery中找到更多容器示例。
该布局中每个图像使用一个Container来添加一个圆形的灰色边框和边距。然后使用容器将列背景颜色更改为浅灰色。
Dart code: main.dart, snippet belowImages: imagesPubspec: pubspec.yaml
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
var container = new Container(
decoration: new BoxDecoration(
color: Colors.black26,
),
child: new Column(
children: [
new Row(
children: [
new Expanded(
child: new Container(
decoration: new BoxDecoration(
border: new Border.all(width: 10.0, color: Colors.black38),
borderRadius:
const BorderRadius.all(const Radius.circular(8.0)),
),
margin: const EdgeInsets.all(4.0),
child: new Image.asset('images/pic1.jpg'),
),
),
new Expanded(
child: new Container(
decoration: new BoxDecoration(
border: new Border.all(width: 10.0, color: Colors.black38),
borderRadius:
const BorderRadius.all(const Radius.circular(8.0)),
),
margin: const EdgeInsets.all(4.0),
child: new Image.asset('images/pic2.jpg'),
),
),
],
),
],
),
);
//...
}
}
使用GridView将widget放置为二维列表。 GridView提供了两个预制list,或者您可以构建自定义网格。当GridView检测到其内容太长而不适合渲染框时,它会自动滚动。
注意: 在显示二维列表时,重要的是单元格占用哪一行和哪一列时, 应该使用Table或 DataTable。
使用GridView.extent 创建最大宽度为150像素的网格Dart code: main.dart, snippet belowImages: imagesPubspec: pubspec.yaml
使用GridView.count 在纵向模式下创建两个行的grid,并在横向模式下创建3个行的网格。通过为每个GridTile设置footer属性来创建标题。Dart code: grid_list_demo.dart from the Flutter Gallery
// The images are saved with names pic1.jpg, pic2.jpg...pic30.jpg.
// The List.generate constructor allows an easy way to create
// a list when objects have a predictable naming pattern.
List<Container> _buildGridTileList(int count) {
return new List<Container>.generate(
count,
(int index) =>
new Container(child: new Image.asset('images/pic${index+1}.jpg')));
}
Widget buildGrid() {
return new GridView.extent(
maxCrossAxisExtent: 150.0,
padding: const EdgeInsets.all(4.0),
mainAxisSpacing: 4.0,
crossAxisSpacing: 4.0,
children: _buildGridTileList(30));
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Center(
child: buildGrid(),
),
);
}
}
ListView是一个类似列的widget,它的内容对于其渲染框太长时会自动提供滚动。
使用ListView显示多个ListTile的业务列表。分隔线将剧院与餐厅分开
Dart code: main.dart, snippet belowIcons: Icons classPubspec: pubspec.yaml
使用ListView控件来显示Material Design palette中的ColorsDart code: Flutter Gallery中的 colors_demo.dart
List<Widget> list = <Widget>[
new ListTile(
title: new Text('CineArts at the Empire',
style: new TextStyle(fontWeight: FontWeight.w500, fontSize: 20.0)),
subtitle: new Text('85 W Portal Ave'),
leading: new Icon(
Icons.theaters,
color: Colors.blue[500],
),
),
new ListTile(
title: new Text('The Castro Theater',
style: new TextStyle(fontWeight: FontWeight.w500, fontSize: 20.0)),
subtitle: new Text('429 Castro St'),
leading: new Icon(
Icons.theaters,
color: Colors.blue[500],
),
),
];
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return new Scaffold(
// ...
body: new Center(
child: new ListView(
children: list,
),
),
);
}
}
使用Stack来组织需要重叠的widget。widget可以完全或部分重叠底部widget。
使用Stack叠加Container(在半透明的黑色背景上显示其文本),放置在Circle Avatar的顶部。Stack使用alignment属性和调整文本偏移。Dart code: main.dart, snippet belowImage: imagesPubspec: pubspec.yaml
使用Stack将gradient叠加到图像的顶部。gradient确保工具栏的图标与图片不同。Dart code: contacts_demo.dart
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
var stack = new Stack(
alignment: const Alignment(0.6, 0.6),
children: [
new CircleAvatar(
backgroundImage: new AssetImage('images/pic.jpg'),
radius: 100.0,
),
new Container(
decoration: new BoxDecoration(
color: Colors.black45,
),
child: new Text(
'Mia B',
style: new TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
],
);
// ...
}
}
Material Components 库中的Card包含相关内容块,可以由大多数类型的widget构成,但通常与ListTile一起使用。Card有一个子项, 但它可以是支持多个子项的列,行,列表,网格或其他小部件。默认情况下,Card将其大小缩小为0像素。您可以使用SizedBox来限制Card的大小。
在Flutter中,Card具有圆角和阴影,这使它有一个3D效果。更改Card的elevation属性允许您控制投影效果。 例如,将elevation设置为24.0,将会使Card从视觉上抬离表面并使阴影变得更加分散。 有关支持的elevation值的列表,请参见Material guidelines中的Elevation and Shadows。 如果指定不支持的值将会完全禁用投影 。
包含3个ListTiles并通过用SizedBox包装进行大小调整的Card。分隔线分隔第一个和第二个ListTiles。Dart code: main.dart, snippet belowIcons: Icons classPubspec: pubspec.yaml
包含图像和文字的CardDart code: cards_demo.dart from the Flutter Gallery
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
var card = new SizedBox(
height: 210.0,
child: new Card(
child: new Column(
children: [
new ListTile(
title: new Text('1625 Main Street',
style: new TextStyle(fontWeight: FontWeight.w500)),
subtitle: new Text('My City, CA 99984'),
leading: new Icon(
Icons.restaurant_menu,
color: Colors.blue[500],
),
),
new Divider(),
new ListTile(
title: new Text('(408) 555-1212',
style: new TextStyle(fontWeight: FontWeight.w500)),
leading: new Icon(
Icons.contact_phone,
color: Colors.blue[500],
),
),
new ListTile(
title: new Text('costa@example.com'),
leading: new Icon(
Icons.contact_mail,
color: Colors.blue[500],
),
),
],
),
),
);
//...
}
ListTile是Material Components库中的一个专门的行级widget,用于创建包含最多3行文本和可选的行前和行尾图标的行。ListTile在Card或ListView中最常用,但也可以在别处使用。
包含3个ListTiles的CardDart code: See Card examples.
使用ListTile列出3个下拉按钮类型。Dart code: buttons_demo.dart from the Flutter Gallery