我正在尝试实现一个简单的网页视图,带有应用栏、内容和页脚。 我正在努力解决页脚的位置。
我想要什么:
我看到几个答案对我的第2个要求有帮助(例如如何使用Flutter创建带有固定页脚的滚动视图?),但对第三个要求没有帮助:在我找到的答案中,内容不包含整个可用空间,并粘在顶部。
到目前为止我找到的解决方案有效:它具有我想要的行为。但不太优雅。
我使用了以下结构:
Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SizedBox(
height: 100,
child: MyAppBar(),
),
Expanded(
child: SingleChildScrollView(
child: Column(
children: [
SizedBox(height: bottomSizedBoxHeight),
Column(
key: childrenColumnKey,
children: [
Container(color: Colors.red, width: 300, height: 300),
Container(color: Colors.green, width: 300, height: 300),
Container(color: Colors.amber, width: 300, height: 300),
],
),
SizedBox(height: bottomSizedBoxHeight),
const SizedBox(
height: 150,
child: MyFooter(),
),
],
),
),
),
],
),
);
在这里您可以看到 2 个 SizedBox,其高度是在运行时计算的。
计算如下:
@override
void didChangeDependencies() {
super.didChangeDependencies();
scheduleMicrotask(() {
double pageWidgetsHeight = childrenColumnKey.currentContext?.size?.height ?? 0;
// Total height of space available is screen height - appBar (100) - footer (150)
double totalHeight = max(0, MediaQuery.of(context).size.height - pageWidgetsHeight - 100 - 150);
setState(() {
topSizedBoxHeight = totalHeight / 2;
bottomSizedBoxHeight = totalHeight / 2;
});
});
}
正如你所看到的,不是很优雅。我计算小部件构建后的总剩余空间,以创建 2 个具有剩余空间的盒子。
这给了我只有 1 个红色方块的结果:
这是当我添加其他方块时,页脚被正确隐藏:
但我不喜欢我实现这一目标的方式。如果有人知道如何实现这一点!
谢谢!
我终于找到了解决方案:使用
Slivers
。
这是实现此目的的代码示例:
Scaffold(
appBar: AppBar(
title: Text('Title'),
),
body: CustomScrollView(
slivers: [
SliverList(
delegate: SliverChildListDelegate(
[
Column(
children: [
Container(color: Colors.red, width: 300, height: 300),
Container(color: Colors.green, width: 300, height: 300),
Container(color: Colors.amber, width: 300, height: 300),
],
),
],
),
),
SliverFillRemaining(
hasScrollBody: false,
child: Align(
alignment: Alignment.bottomCenter,
child: Container(color: Colors.orange),
),
)
],
),
);
这将是另一种方式...我不知道它是否更漂亮:D
void main() {
runApp(TheApp());
}
class TheApp extends StatelessWidget {
const TheApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final red = Colors.red.withOpacity(0.5);
return MaterialApp(
home: Scaffold(
appBar: AppBar(),
body: MyHome(),
),
);
}
}
class MyHome extends StatelessWidget {
const MyHome({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
height: MediaQuery.of(context).size.height,
color: Colors.white,
child: Column(
children: [
Expanded(
child: ListView(
children: [
LayoutBuilder(builder: (context, constraints) {
return SizedBox(
height: MediaQuery.of(context).size.height -
56, //56==height of AppBar
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(color: Colors.red, width: 300, height: 300),
// Container(color: Colors.green, width: 300, height: 300),
// Container(color: Colors.amber, width: 300, height: 300),
Spacer(),
AppBar(),
],
),
);
}),
],
),
),
],
),
);
}
}