调用scrollController.animateTo时在ListView上滚动

问题描述 投票:0回答:1

我有一个像这样的ListView.builder:

ListView.builder(
  key: _listViewKey,
  controller: widget.scrollController,
  shrinkWrap: true,
  scrollDirection: Axis.vertical,
  physics: const AlwaysScrollableScrollPhysics(),
  itemCount: state.items,
  itemBuilder: (context, index) {
  ...

此外,我有一个滚动到结束方法,该方法使用scrollController调用animateTo将用户带到列表的底部,无论他们滚动到哪里。这是该方法:

void scrollToEnd() async {
   await Future.delayed(const Duration(milliseconds: 300));
   Future.doWhile(() {
     if (widget.scrollController.positions.last.extentAfter == 0) {
       return Future.value(false);
     }
     return widget.scrollController.animateTo(widget.scrollController.positions.last.maxScrollExtent, duration: Duration(milliseconds: 500), curve: Curves.linear).then((value) => true);
   });
}

我发现只调用一次 animateTo 并不总是足够的,有时滚动并没有一直到达底部,所以开发了这个 doWhile 方法。

但是现在,当向上滚动列表中的一些项目并调用 scrollToEnd() 时,似乎出现了相当严重的过度滚动,并且显示了全部空白,直到最后一个列表项目最终回到视图中。我有两个问题:

  1. 为什么 widget.scrollController.positions.last.maxScrollExtent 返回的值比列表实际的值更高?
  2. 如何阻止这种过度滚动的发生?我唯一的目标是 scrollToEnd() 每次都能将列表拖到末尾,而且这样做时看起来并不奇怪。
flutter dart
1个回答
0
投票

您遇到的过度滚动问题可能是由于报告的 maxScrollExtent 与实际列表大小之间的差异所致。

这是您的scrollToEnd方法的修订版本:

void scrollToEnd() async {
  await Future.delayed(const Duration(milliseconds: 300));
  final double itemHeight = // Calculate the height of each item in the list;
  final double totalHeight = state.items * itemHeight; // Calculate the total height of the list
  widget.scrollController.animateTo(
    totalHeight,
    duration: Duration(milliseconds: 500),
    curve: Curves.linear,
  );
}

注意: 确保 itemHeight 准确表示列表中每个项目的高度。如果您的列表项具有可变高度,您可能需要更复杂的方法来计算总高度。

© www.soinside.com 2019 - 2024. All rights reserved.