列表视图,滚动页脚在底部
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了列表视图,滚动页脚在底部相关的知识,希望对你有一定的参考价值。
我正在尝试创建一个滚动列表小部件,它显示一些项目,并能够在底部添加一个页脚滚动。
如果滚动列表没有占据整个高度,例如只有2个项目,页脚仍应出现在屏幕的底部。以下是我正在努力实现的一些草图
我尝试计算listview需要的垂直大小,但这意味着我需要知道构建时孩子的高度。有没有更好的办法?
编辑 我正在努力实现与here完全相同的东西,但当然还有Flutter。
答案
您需要为此创建自定义RenderBox。因为没有小工具可以支持这种开箱即用的功能。
SliverFillRemaining
非常接近。但它的大小/滚动行为与您期望的不同。因为,如果存在,将几乎总是使Scrollable
...可滚动。
相反,我们可以复制粘贴SliverFillRemaining
的来源。并做一些编辑
class SliverFooter extends SingleChildRenderObjectWidget
/// Creates a sliver that fills the remaining space in the viewport.
const SliverFooter(
Key key,
Widget child,
) : super(key: key, child: child);
@override
RenderSliverFooter createRenderObject(BuildContext context) => new RenderSliverFooter();
class RenderSliverFooter extends RenderSliverSingleBoxAdapter
/// Creates a [RenderSliver] that wraps a [RenderBox] which is sized to fit
/// the remaining space in the viewport.
RenderSliverFooter(
RenderBox child,
) : super(child: child);
@override
void performLayout()
final extent = constraints.remainingPaintExtent - math.min(constraints.overlap, 0.0);
var childGrowthSize = .0; // added
if (child != null)
// changed maxExtent from 'extent' to double.infinity
child.layout(constraints.asBoxConstraints(minExtent: extent, maxExtent: double.infinity), parentUsesSize: true);
childGrowthSize = constraints.axis == Axis.vertical ? child.size.height : child.size.width; // added
final paintedChildSize = calculatePaintOffset(constraints, from: 0.0, to: extent);
assert(paintedChildSize.isFinite);
assert(paintedChildSize >= 0.0);
geometry = new SliverGeometry(
// used to be this : scrollExtent: constraints.viewportMainAxisExtent,
scrollExtent: math.max(extent, childGrowthSize),
paintExtent: paintedChildSize,
maxPaintExtent: paintedChildSize,
hasVisualOverflow: extent > constraints.remainingPaintExtent || constraints.scrollOffset > 0.0,
);
if (child != null)
setChildParentData(child, constraints, geometry);
在这里,我改变了一件事
- 不受限制的孩子
maxExtent
。因为如果没有更多的屏幕空间可用,那将对页脚强制执行0的高度。 - 将
SliverGeometry
scrollExtent
从“全屏高度”改为“实际可用尺寸”。因此它实际上只填充剩余的可见空间。没有填满屏幕。 - 为同一个
scrollExtent
添加了一个最小值,等于实际的页脚高度。因此,如果视口中没有剩余空间,则只需添加子项,而不会在其周围添加任何空格。
我们现在可以像往常一样在我们的CustomScrollView
中使用它。
最终结果 :
new CustomScrollView(
slivers: <Widget>[
new SliverFixedExtentList(
itemExtent: 42.0,
delegate: new SliverChildBuilderDelegate((context, index)
return new SizedBox.expand(
child: new Card(),
);
, childCount: 42),
),
new SliverFooter(
child: new Align(
alignment: Alignment.bottomCenter,
child: new Container(
height: 42.0,
color: Colors.red,
),
),
),
],
),
另一答案
这可以通过使用具有特殊约束的SingleChildScrollView
来实现,如here所述。
看看下面的例子:
@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>[
Container(height: 200, color: Colors.blue),
Container(height: 200, color: Colors.orange),
Container(height: 200, color: Colors.green),
Container(height: 50, color: Colors.pink),
Expanded(
child: Align(
alignment: Alignment.bottomCenter,
child: Container(
width: double.infinity,
color: Colors.red,
padding: EdgeInsets.all(12.0),
child: Text('FOOTER', textAlign: TextAlign.center,),
),
),
),
],
),
),
),
);
);
如果您将粉红色容器的高度更改为更大的值(例如500),您将看到页脚也会滚动整个列表。
感谢Simon Lightfoot的帮助,指导我朝着正确的方向前进!
另一答案
像https://flutter.io/web-analogs/#setting-absolute-position这样的东西?这似乎导致小部件停留在屏幕上的固定位置。
以上是关于列表视图,滚动页脚在底部的主要内容,如果未能解决你的问题,请参考以下文章