1.Padding
在 html 中常见的布局标签都有 padding 属性,但是 Flutter 中很多 Widget 是没有 padding 属性。这个时候我们可以用 Padding 组件处理容器与子元素直接的间距。
这是一个网格列表:
return GridView.count(
crossAxisCount: 2,//列数
childAspectRatio: 1.7,//表格宽高比例
Image.network('https://cdn.pixabay.com/photo/2023/03/09/20/02/cat-7840767_640.jpg',
fit: BoxFit.cover,//填充网格
),
Image.network('https://cdn.pixabay.com/photo/2023/03/08/10/11/crocuses-7837426__340.jpg',fit: BoxFit.cover,),
Image.network('https://cdn.pixabay.com/photo/2023/03/09/02/53/girl-7839121__340.jpg',fit: BoxFit.cover,),
Image.network('https://cdn.pixabay.com/photo/2023/03/06/15/29/bee-7833738__340.jpg',fit: BoxFit.cover,),
Image.network('https://cdn.pixabay.com/photo/2023/03/07/13/18/fruit-7835730__340.jpg',fit: BoxFit.cover,),
Image.network('https://cdn.pixabay.com/photo/2013/11/28/10/36/road-220058__340.jpg',fit: BoxFit.cover,),
Image.network('https://cdn.pixabay.com/photo/2023/03/09/20/02/cat-7840767_640.jpg',fit: BoxFit.cover,),
Image.network('https://cdn.pixabay.com/photo/2023/03/08/10/11/crocuses-7837426__340.jpg',fit: BoxFit.cover,),
Image.network('https://cdn.pixabay.com/photo/2023/03/09/02/53/girl-7839121__340.jpg',fit: BoxFit.cover,),
Image.network('https://cdn.pixabay.com/photo/2023/03/06/15/29/bee-7833738__340.jpg',fit: BoxFit.cover,),
Image.network('https://cdn.pixabay.com/photo/2023/03/07/13/18/fruit-7835730__340.jpg',fit: BoxFit.cover,),
Image.network('https://cdn.pixabay.com/photo/2013/11/28/10/36/road-220058__340.jpg',fit: BoxFit.cover,),
],
);
因为image组件没有padding属性,所以我们在Padding中来设置image:
return GridView.count(
crossAxisCount: 2, //列数
childAspectRatio: 1.7, //表格宽高比例
children: [
Padding(
padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
child: Image.network(
'https://cdn.pixabay.com/photo/2023/03/09/20/02/cat-7840767_640.jpg',
fit: BoxFit.cover, //填充网格
),
),
Padding(
padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
child: Image.network(
'https://cdn.pixabay.com/photo/2023/03/08/10/11/crocuses-7837426__340.jpg',
fit: BoxFit.cover,
),
),
Padding(
padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
child: Image.network(
'https://cdn.pixabay.com/photo/2023/03/09/02/53/girl-7839121__340.jpg',
fit: BoxFit.cover,
),
),
Padding(
padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
child: Image.network(
'https://cdn.pixabay.com/photo/2023/03/06/15/29/bee-7833738__340.jpg',
fit: BoxFit.cover,
),
),
Padding(
padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
child: Image.network(
'https://cdn.pixabay.com/photo/2023/03/07/13/18/fruit-7835730__340.jpg',
fit: BoxFit.cover,
),
),
Padding(
padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
child: Image.network(
'https://cdn.pixabay.com/photo/2013/11/28/10/36/road-220058__340.jpg',
fit: BoxFit.cover,
),
),
Padding(
padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
child: Image.network(
'https://cdn.pixabay.com/photo/2023/03/09/20/02/cat-7840767_640.jpg',
fit: BoxFit.cover,
),
),
Padding(
padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
child: Image.network(
'https://cdn.pixabay.com/photo/2023/03/08/10/11/crocuses-7837426__340.jpg',
fit: BoxFit.cover,
),
),
Padding(
padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
child: Image.network(
'https://cdn.pixabay.com/photo/2023/03/09/02/53/girl-7839121__340.jpg',
fit: BoxFit.cover,
),
),
Padding(
padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
child: Image.network(
'https://cdn.pixabay.com/photo/2023/03/06/15/29/bee-7833738__340.jpg',
fit: BoxFit.cover,
),
),
Padding(
padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
child: Image.network(
'https://cdn.pixabay.com/photo/2023/03/07/13/18/fruit-7835730__340.jpg',
fit: BoxFit.cover,
),
),
Padding(
padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
child: Image.network(
'https://cdn.pixabay.com/photo/2013/11/28/10/36/road-220058__340.jpg',
fit: BoxFit.cover,
),
),
]);
效果如下:
但是此时最右边不是我们期望的样子,我们希望最右侧也有10的距离,那么我们可以将整个GridView放入Padding中,如下:
最后样式:
2.Row 水平布局组件
示例代码:
class HomeContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return IconContainer(Icons.home,color: Colors.blue,);
}
}
class IconContainer extends StatelessWidget{
double? size=32.0;
Color? color=Colors.red;
IconData icon;
IconContainer(this.icon,{
this.size,this.color});
@override
Widget build(BuildContext context) {
// TODO: implement build
return Container(
height: 100,
width: 100,
color: this.color,
child: Icon(this.icon,size: this.size,color: Colors.lightGreen,),
);
}
}
我们可以使用Row进行水平布局:
mainAxisAlignment和crossAxisAlignment的使用示例:
return Container(
width: 400,
height: 600,
color: Colors.green,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, //主轴排序方式
crossAxisAlignment: CrossAxisAlignment.stretch, //次轴的排序方式,较少用
children: [
IconContainer(
Icons.home,
color: Colors.blue,
),
IconContainer(
Icons.home,
color: Colors.red,
),
IconContainer(
Icons.home,
color: Colors.amber,
),
],
),
);
3.Coloum垂直布局
其使用方式以及相关参数与row完全相同:
return Container(
width: 400,
height: 600,
color: Colors.green,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, //主轴排序方式
crossAxisAlignment: CrossAxisAlignment.stretch, //次轴的排序方式,较少用
children: [
IconContainer(
Icons.home,
color: Colors.blue,
),
IconContainer(
Icons.home,
color: Colors.red,
),
IconContainer(
Icons.home,
color: Colors.amber,
),
],
),
);
水平及垂直布局主轴不同,水平布局主轴是x轴,垂直主轴是y轴
4.Expanded
expanded常与row和colunm一起使用。
常用属性flex作用是控制元素占整个父 Row /Column 的比例
return Row(
children: [
Expanded(
flex: 1,
child: IconContainer(
Icons.home,
color: Colors.blue,
),),
Expanded(
flex: 2,
child: IconContainer(
Icons.home,
color: Colors.red,
),),
],
);
当一侧使用expanded,另一侧不使用时,使用expanded的一侧将自适应:
return Row(
children: [
Expanded(
flex: 1,
child: IconContainer(
Icons.home,
color: Colors.blue,
),
),
IconContainer(
Icons.home,
color: Colors.red,
),
],
);
练习:
实现类似这样的布局
return Column(
children: [
Container(
height: 180,
color: Colors.black,
),
SizedBox(height: 10,),
Row(
children: [
Expanded(
flex: 2,
child: Container(
height: 180,
child: Image.network('https://cdn.pixabay.com/photo/2023/03/07/13/18/fruit-7835730__340.jpg',fit: BoxFit.cover,),
)),
SizedBox(width: 10,),
Expanded(
flex: 1,
child: Container(
height: 180,
child: ListView(
children: [
Container(
//height: 90,
child: Image.network('https://cdn.pixabay.com/photo/2023/03/08/10/11/crocuses-7837426__340.jpg'),
),
SizedBox(height: 10,),
Container(
//height: 90,
child: Image.network('https://cdn.pixabay.com/photo/2023/03/09/20/02/cat-7840767_640.jpg'),
)
],
)
),
)
],
)
],
);
对间距的控制要灵活应用SizedBox
效果如下:
5.Wrap流式布局
Wrap 可以实现流布局,单行的 Wrap 跟 Row 表现几乎一致,单列的 Wrap 则跟 Column 表现几乎一致。但 Row 与 Column 都是单行单列的,Wrap 则突破了这个限制,mainAxis 上空间不足时,则向crossAxis上去扩展显示。