Flutter 颤振-如何使小部件在';s滚动到屏幕上
我创建了一个自定义小部件,将页脚作为最后一项添加到接收到的可滚动小部件中。一切正常,但我想更改创建页脚的时间 就像Flutter 颤振-如何使小部件在';s滚动到屏幕上,flutter,dart,flutter-layout,flutter-widget,Flutter,Dart,Flutter Layout,Flutter Widget,我创建了一个自定义小部件,将页脚作为最后一项添加到接收到的可滚动小部件中。一切正常,但我想更改创建页脚的时间 就像ListView.builder在项目滚动到屏幕上时创建项目一样,我希望页脚也能这样。如果此自定义小部件接收到ListView.builder或GridView.builder,则它们的项目在滚动到屏幕上时创建得很好,但页脚是第一次创建的,即使它不在屏幕上 这里是自定义小部件,其中接收的小部件是widget.child(ScrollView),页脚是widget.footer(wid
ListView.builder
在项目滚动到屏幕上时创建项目一样,我希望页脚也能这样。如果此自定义小部件接收到ListView.builder
或GridView.builder
,则它们的项目在滚动到屏幕上时创建得很好,但页脚是第一次创建的,即使它不在屏幕上
这里是自定义小部件,其中接收的小部件是widget.child
(ScrollView
),页脚是widget.footer
(widget
)
我就是这样使用它的:
ScrollableWithFooter(
child: ListView.builder(
itemCount: 50,
itemBuilder: (context, index) {
print(index);
return SizedBox(height: 400, child: Text('Item $index'));
},
),
footer: Center(child: Text('Footer')),
)
在50个列表中,我看到屏幕上的第一个项目,这是打印输出:
I/flutter (28472): 0
I/flutter (28472): 1
I/flutter (28472): 2
I/flutter (28472): footer
@override
Widget build(BuildContext context) {
return Scrollable(
controller: widget.child.controller,
axisDirection: widget.child.getDirection(context),
viewportBuilder: (context, offset) {
return ShrinkWrappingViewport(
axisDirection: widget.child.getDirection(context),
offset: offset,
slivers: widget.child.buildSlivers(context)
..add(SliverList(
delegate: SliverChildBuilderDelegate(
(_, index) => index < 2 ? SizedBox.shrink() : widget.footer,
childCount: 3))),
);
},
);
}
当我开始滚动时,其他项目开始在创建索引时打印它们的索引:
I/flutter (28472): 2
I/flutter (28472): footer
I/flutter (28472): 3
I/flutter (28472): 4
I/flutter (28472): 5
这适用于项目,但不适用于页脚。我希望在到达列表末尾时创建页脚,就像其他项目一样。如何才能做到这一点
请注意,在屏幕上一切正常,页脚显示在列表的末尾。只有它的创造在它应该发生之前发生
这是我尝试过的,但不起作用:
@override
Widget build(BuildContext context) {
return Scrollable(
controller: widget.child.controller,
axisDirection: widget.child.getDirection(context),
viewportBuilder: (context, offset) {
List<Widget> slivers = widget.child.buildSlivers(context);
return ShrinkWrappingViewport(
axisDirection: widget.child.getDirection(context),
offset: offset,
slivers: [
SliverList(
delegate: SliverChildBuilderDelegate((context, index) {
if (index < slivers.length) {
return slivers[index]; // <- Here seems to be the problem
}
print('footer');
return widget.footer;
}, childCount: slivers.length + 1))
],
);
},
);
}
@覆盖
小部件构建(构建上下文){
返回可滚动(
控制器:widget.child.controller,
axisDirection:widget.child.getDirection(上下文),
视口生成器:(上下文,偏移){
List slivers=widget.child.buildSlivers(上下文);
返回收缩包装可视端口(
axisDirection:widget.child.getDirection(上下文),
抵销:抵销,
条子:[
银表(
委托:SliverChildBuilderDelegate((上下文,索引){
if(指数<条长度){
返回条[索引];//您可以向listview的控制器添加一个侦听器,它将侦听滚动,当您触底时,您将激活一个名为footer的标志,然后显示页脚。我找到了一种方法。我做得很好,因为某种原因,SliverChildBuilderDelegate
总是创建前两个元素,即使它们没有滚动到屏幕上。因此,我必须创建两个虚拟的不可见页脚,然后是真实的页脚,这样,当它们滚动到屏幕上时,就会创建真实的页脚:
@override
Widget build(BuildContext context) {
return Scrollable(
controller: widget.child.controller,
axisDirection: widget.child.getDirection(context),
viewportBuilder: (context, offset) {
return ShrinkWrappingViewport(
axisDirection: widget.child.getDirection(context),
offset: offset,
slivers: widget.child.buildSlivers(context)
..add(SliverList(
delegate: SliverChildBuilderDelegate((context, index) {
if (index < 2) {
print('dummy footer');
return SizedBox.shrink();
}
print('footer');
return widget.footer;
}, childCount: 3))),
);
},
);
@覆盖
小部件构建(构建上下文){
返回可滚动(
控制器:widget.child.controller,
axisDirection:widget.child.getDirection(上下文),
视口生成器:(上下文,偏移){
返回收缩包装可视端口(
axisDirection:widget.child.getDirection(上下文),
抵销:抵销,
片段:widget.child.buildSlivers(上下文)
…添加(滑动列表)(
委托:SliverChildBuilderDelegate((上下文,索引){
如果(指数<2){
打印(“伪页脚”);
返回SizedBox.shrink();
}
打印(‘页脚’);
返回widget.footer;
},儿童人数:3),
);
},
);
这将是没有指纹的最终解决方案:
I/flutter (28472): 0
I/flutter (28472): 1
I/flutter (28472): 2
I/flutter (28472): footer
@override
Widget build(BuildContext context) {
return Scrollable(
controller: widget.child.controller,
axisDirection: widget.child.getDirection(context),
viewportBuilder: (context, offset) {
return ShrinkWrappingViewport(
axisDirection: widget.child.getDirection(context),
offset: offset,
slivers: widget.child.buildSlivers(context)
..add(SliverList(
delegate: SliverChildBuilderDelegate(
(_, index) => index < 2 ? SizedBox.shrink() : widget.footer,
childCount: 3))),
);
},
);
}
@覆盖
小部件构建(构建上下文){
返回可滚动(
控制器:widget.child.controller,
axisDirection:widget.child.getDirection(上下文),
视口生成器:(上下文,偏移){
返回收缩包装可视端口(
axisDirection:widget.child.getDirection(上下文),
抵销:抵销,
片段:widget.child.buildSlivers(上下文)
…添加(滑动列表)(
代表:SliverChildBuilderDelegate(
(\ux,index)=>index<2?SizedBox.shrink():widget.footer,
儿童人数:3人),
);
},
);
}
现在,自定义小部件在任何滚动视图的底部有效地添加了一个页脚,只有当滚动到屏幕上时,才会创建滚动视图和页脚的项目
如果有人找到更好的方法,请告诉我。目前,我同意此解决方案。为什么不在列表中的最后一项插入一个空字符串或null。在小部件(列表中每个项目使用的小部件)中检查列表是否在最后一个索引处,以及最后一个索引是否为空或null。如果是渲染页脚。我认为这应该可以解决您的问题,以前尝试过类似的方法。我如何做到这一点?我收到一个ScrollView小部件,我无法修改其列表。如果使用动画呢?制作页脚,使用动画控件将其缩放为零呃,在滚动到底部后,使用动画控制器将其缩小。尝试一下,可能会奏效。这种方法的问题是,如果我滚动到最后,滚动停止(因为没有页脚),然后我调用setState()来显示页脚,然后我必须再次手动滚动以查看页脚。