我想创建一个视图,该视图必须具有Column
和滚动视图(例如SingleChildScrollView
之类)和页脚,而与屏幕大小无关。如果屏幕足够大,它将使用滚动条和页脚之间的空白空间;如果不足够,它将展开并且仅使页脚上方的小部件可滚动。
它或多或少像Listview with scrolling Footer at the bottom,但有一个不同,我希望键盘溢出页脚,并且它也应该留在原处。
类似
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.only(left: 30.0, right: 30.0, top: 80.0),
child: Form(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
// Multiple widgets and form fields
],
),
),
),
),
Padding(
padding: const EdgeInsets.only(top: 50.0),
child: SafeArea(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
// Footer widgets
],
),
),
)
],
),
);
答案 0 :(得分:3)
对于那些希望以简单的方式实现仅带有滚动视图的页脚的人,下面的代码可能会有所帮助:
Scaffold(
appBar: buildAppBar('Some cool appbar'),
body: Column(
children: [
Expanded(
child: SingleChildScrollView(
child: Column(
children: [
PackageCard(),
PackageCard(),
PackageCard(),
],
),
),
),
Container(
child: Text('Your super cool Footer'),
color: Colors.amber,
)
],
),
);
视觉表现:-
---Column
|
|---Expanded--
|-SingleChildScrollView (column /YOUR SCROLLABLE VIEW)
|
|-Container(YOUR FOOTER)
我在这里使用了 expanded
和 SinglechildScrollView
答案 1 :(得分:2)
困难在于Column
和SingleChildScrollView
很难一起工作,因为其中一个需要约束,而另一个需要约束。
诀窍是使用CustomMultiChildLayout
自己进行计算。 MediaQuery
的帮助下获得了键盘的大小,以便页脚可以消失以为内容留出更多空间。
这是一个可重复使用的小部件,可以为您完成此操作:
class FooterLayout extends StatelessWidget {
const FooterLayout({
Key key,
@required this.body,
@required this.footer,
}) : super(key: key);
final Container body;
final Container footer;
@override
Widget build(BuildContext context) {
return CustomMultiChildLayout(
delegate: _FooterLayoutDelegate(MediaQuery.of(context).viewInsets),
children: <Widget>[
LayoutId(
id: _FooterLayout.body,
child: body,
),
LayoutId(
id: _FooterLayout.footer,
child: footer,
),
],
);
}
}
enum _FooterLayout {
footer,
body,
}
class _FooterLayoutDelegate extends MultiChildLayoutDelegate {
final EdgeInsets viewInsets;
_FooterLayoutDelegate(this.viewInsets);
@override
void performLayout(Size size) {
size = Size(size.width, size.height + viewInsets.bottom);
final footer =
layoutChild(_FooterLayout.footer, BoxConstraints.loose(size));
final bodyConstraints = BoxConstraints.tightFor(
height: size.height - max(footer.height, viewInsets.bottom),
width: size.width,
);
final body = layoutChild(_FooterLayout.body, bodyConstraints);
positionChild(_FooterLayout.body, Offset.zero);
positionChild(_FooterLayout.footer, Offset(0, body.height));
}
@override
bool shouldRelayout(MultiChildLayoutDelegate oldDelegate) {
return true;
}
}
照这样使用:
FooterLayout(
body: body,
footer: footer,
),
答案 2 :(得分:1)
我解决的方法是将固定的Footer
和SingleChildScrollView
包装在Stack
小部件中,然后相应地对齐Footer
。
class ScrollableFooter extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
SingleChildScrollView(
child: Container(
padding: EdgeInsets.all(5),
child: Column(
children: <Widget>[
// Your body widgets here
],
),
),
),
Align(
alignment: Alignment.bottomCenter,
child: // Your fixed Footer here,
),
],
);
}
}
答案 3 :(得分:1)
公认的解决方案在许多情况下都有效,但是当您想使用 ListView 之类的东西时,它会变得棘手,因为它无法提供固有高度。我试图找到一些不同的解决方案,结果证明我可以,而且看起来更灵活。我设法使用条子解决了这种情况。内容在一个细长条内,而页脚也在一个细长条内。
提示:观看“The Boring Flutter Development Show, Ep. 12”,这都是关于条子的。
1
答案 4 :(得分:0)
尽管Rémi的答案是正确的,但实际上我已经找到了一种简单的方法,只需将LayoutBuilder
与Intrinsic Height
结合起来即可实现自己的目标。
class ScrollableFooter extends StatelessWidget {
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
return SingleChildScrollView(
child: ConstrainedBox(
constraints: constraints.copyWith(
minHeight: constraints.maxHeight,
maxHeight: double.infinity,
),
child: IntrinsicHeight(
child: Column(
children: <Widget>[
// Your body widgets here
Expanded(
child: Align(
alignment: Alignment.bottomCenter,
child: // Your footer widget
),
),
],
),
),
),
);
});
}
}
答案 5 :(得分:0)
尽管公认的答案似乎在移动设备上有效,但是当宽度大于高度时会出现问题。发生这种情况时,IntrinsicHeight
就像AspectRatio
一样,并且高度增加,因此页脚被推离屏幕。
我认为问题在于IntrinsicHeight
内部工作方式所使用的定义:
...而是将其自身调整为更合理的高度。
我可以确认@Rémi的解决方案在这种情况下也适用。
它应该是Flutter框架提供的标准小部件。