目标:
1)Flutter Widget组件之间间距怎么表示?
2)列表怎么定义子项之间间距?
一、间距的表示组件
列表组件的间距一般采用固定间距,间距占据可见的空间。
已经使用的表示间距的组件
Spacer:调整小部件之间的间距
Expanded:扩展组件以充满空间
但是它们需要指定高度约束。
在列表中添加间距,使用LayoutBuilder和ConstrainedBox在空间足够时均匀地分隔列表项,并允许用户在空间不足时滚动,具体步骤如下:
- Add a LayoutBuilder with a SingleChildScrollView.
- Add a ConstrainedBox inside the SingleChildScrollView.
- Create a Column with spaced items.
二、创建带有SingleChildScrollView的LayoutBuilder
开始创建一个Layout Builder,需要提供一个builder 回调,
带有两个参数:
1. BuilderContext, 由Layout Builder提供
2. 父Widget 的 BoxConstraints
LayoutBuilder(builder: (context, constraints) {
return SingleChildScrollView(
child: Placeholder(),
);
});
三、添加一个ConstrainedBox到
SingleChildScrollView内部
ConstraintdBox小部件向其子部件施加额外的约束。
通过将minHeight参数设置为LayoutBuilder约束的maxHeight来配置约束。
这样可以确保子窗口小部件的最小高度等于LayoutBuilder约束提供的可用空间,即BoxConstraints的最大高度。
LayoutBuilder(builder: (context, constraints) {
return SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(minHeight: constraints.maxHeight),
child: Placeholder(),
),
);
});
但是,您没有设置maxHeight参数,因为您需要允许子项大于LayoutBuilder的大小,以防项目不适合屏幕。
四、创建带间距的Column
最后,添加一个Column作为ConstraintdBox的子级。
要均匀地分配项目的空间,请将mainAxisAlignment设置为mainAxisAlignment.spaceBetween。
import 'package:flutter/material.dart';
void main() => runApp(const SpacedItemsList());
class SpacedItemsList extends StatelessWidget {
const SpacedItemsList({super.key});
@override
Widget build(BuildContext context) {
const items = 4;
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
cardTheme: CardTheme(color: Colors.blue.shade50),
useMaterial3: true,
),
home: Scaffold(
body: LayoutBuilder(builder: (context, constraints) {
return SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(minHeight: constraints.maxHeight),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: List.generate(
items, (index) => ItemWidget(text: 'Item $index')),
),
),
);
}),
),
);
}
}
class ItemWidget extends StatelessWidget {
const ItemWidget({
super.key,
required this.text,
});
final String text;
@override
Widget build(BuildContext context) {
return Card(
child: SizedBox(
height: 100,
child: Center(child: Text(text)),
),
);
}
}