Flutter ListVIew没有';t再次构建后,滚动至正确的偏移位置
我希望listview以偏移量开始。我正试图通过在ListView中使用下面的代码来实现 控制器:ScrollController(初始ScrollOffset:30*项目高度) 最初,在第一次加载时,将使用正确的偏移量加载列表 当从父窗口小部件调用set state再次构建列表时,列表将更新,但滚动偏移量的行为异常 有两种情况:Flutter ListVIew没有';t再次构建后,滚动至正确的偏移位置,flutter,Flutter,我希望listview以偏移量开始。我正试图通过在ListView中使用下面的代码来实现 控制器:ScrollController(初始ScrollOffset:30*项目高度) 最初,在第一次加载时,将使用正确的偏移量加载列表 当从父窗口小部件调用set state再次构建列表时,列表将更新,但滚动偏移量的行为异常 有两种情况: 我不滚动列表:在此之后,如果设置状态为“一切正常”。列表将更新,并且始终处于正确的偏移量 我滚动列表:如果我滚动列表,然后重建列表, 滚动偏移关闭了几个项目。列表得到
class DaysManager extends StatelessWidget {
final int daysBeforeFocusDate = 30;
final int totalDaysToInit = 61;
static final double ITEM_HEIGHT = 108.00;
ScrollController scrollController;
List<Day> days;
DaysManager({DateTime focusDate}) {
final DateTime startDate =
focusDate.subtract(Duration(days: daysBeforeFocusDate));
days = List.generate(totalDaysToInit, (int index) {
return Day(
date: startDate.add(
Duration(days: index),
),
);
});
scrollController = ScrollController(initialScrollOffset: 30 *ITEM_HEIGHT);
}
@override
Widget build(BuildContext context) {
return _buildScrollView();
}
ListView _buildScrollView() {
ListView listView = ListView.builder(
cacheExtent: 0,
controller: scrollController,
itemCount: days.length,
itemBuilder: (BuildContext context, int index) {
return days[index];
});
return listView;
}
}
class DaysManager扩展了无状态小部件{
最终int日前焦点日期=30;
最终整数totalDaysToInit=61;
静态最终双项目高度=108.00;
滚动控制器滚动控制器;
列出日期;
DaysManager({DateTime focusDate}){
最终日期时间起始日期=
焦点日期减去(持续时间(天:焦点日期前的天));
days=List.generate(totalDaysToInit,(int索引){
回归日(
日期:startDate.add(
持续时间(天数:指数),
),
);
});
scrollController=scrollController(初始ScrollOffset:30*项目高度);
}
@凌驾
小部件构建(构建上下文){
返回_buildScrollView();
}
ListView_buildScrollView(){
ListView ListView=ListView.builder(
缓存范围:0,
控制器:滚动控制器,
itemCount:days.length,
itemBuilder:(构建上下文,int索引){
返回天数[指数];
});
返回列表视图;
}
}
我联系了Flitter Slack社区,得到了一个有效的答案。都归功于那边的娄州。这是那次谈话的副本
ScrollController
将其滚动位置保存在它所附加到的列表的PageStorage
记录中,而不是它自己的PageStorage记录中。因此,当重新创建小部件时,由于您没有为listview小部件指定新的键
,因此它会重用相同的键(Flatter内部的许多性能优化之一)。可以通过添加两行来解决此问题:
import 'dart:math';
...
ListView listView = ListView.builder(
key: ValueKey<int>(Random(DateTime.now().millisecondsSinceEpoch).nextInt(4294967296)),
...
我联系了FlitterSlack社区,得到了一个有效的答案。都归功于那边的娄州。这是那次谈话的副本
ScrollController
将其滚动位置保存在它所附加到的列表的PageStorage
记录中,而不是它自己的PageStorage记录中。因此,当重新创建小部件时,由于您没有为listview小部件指定新的键
,因此它会重用相同的键(Flatter内部的许多性能优化之一)。可以通过添加两行来解决此问题:
import 'dart:math';
...
ListView listView = ListView.builder(
key: ValueKey<int>(Random(DateTime.now().millisecondsSinceEpoch).nextInt(4294967296)),
...
哪里有这个
scrollController=scrollController(initialScrollOffset:30*项目高度);}代码>?直接在类或方法中?我添加了代码。请看那里。你在哪里有这个scrollController=scrollController(initialScrollOffset:30*项目高度);}代码>?直接在类或方法中?我添加了代码。请看这里。当我意识到我们不想在绘图之间保持滚动位置,而是想将其重置为新选定项的顶部(列表下方正好30个),我理解了问题并创建了解决方案。然后我解释了为什么这是解决方案。谢谢@will luce的呐喊,这太棒了。我们终于找到了解决办法。谢谢你的回答。虽然我需要了解什么是页面存储以及它是如何工作的,但它存储的是什么样的信息。如果您了解更多信息,请解释。PageStorage在许多Flatter核心小部件上保存各种数据的键值对。您甚至可以将其用于自己的小部件。不过,这一切都基于小部件的键。将其视为每个有状态小部件特定数据的全局存储空间。它允许您保存小部件的数据,即使是通过完全销毁小部件,只要您使用相同的键。在许多方面,这就像是颤振的内部状态管理。这是一个关于按键的好视频…还有一篇关于页面存储的文章。当我意识到我们不想在绘图之间保持滚动位置,而是想将其重置为新选定项的顶部(列表下方正好30个),我理解了这个问题并创建了解决方案。然后我解释了为什么这是解决方案。谢谢@will luce的呐喊,这太棒了。我们终于找到了解决办法。谢谢你的回答。虽然我需要了解什么是页面存储以及它是如何工作的,但它存储的是什么样的信息。如果您了解更多信息,请解释。PageStorage在许多Flatter核心小部件上保存各种数据的键值对。您甚至可以将其用于自己的小部件。不过,这一切都基于小部件的键。将其视为每个有状态小部件特定数据的全局存储空间。它允许您保存小部件的数据,即使是通过完全销毁小部件,只要您使用相同的键。在许多方面,这就像是颤振的内部状态管理。这是一个关于密钥的好视频…和一篇关于页面存储的文章