Flutter 在前面插入项目时如何保持滚动位置? 我想要什么

Flutter 在前面插入项目时如何保持滚动位置? 我想要什么,flutter,dart,Flutter,Dart,我想创建一个类似Twitter应用程序的行为。因此,我滚动到列表的顶部,使用CupertinoSliverRefreshControl加载新帖子,并希望将它们放在当前显示列表的顶部,同时保持滚动位置 我的代码是什么样子的 要使用CupertinosLiverRefresh控件,我需要在CustomScrollView中使用sliversonRefreshI加载新帖子并将旧帖子添加到其中: final _scrollController = ScrollController(keepScrollO

我想创建一个类似Twitter应用程序的行为。因此,我滚动到列表的顶部,使用
CupertinoSliverRefreshControl
加载新帖子,并希望将它们放在当前显示列表的顶部,同时保持滚动位置

我的代码是什么样子的 要使用
CupertinosLiverRefresh控件
,我需要在
CustomScrollView
中使用
slivers
onRefresh
I加载新帖子并将旧帖子添加到其中:

final _scrollController = ScrollController(keepScrollOffset: true);


return CustomScrollView(
  controller: _scrollController
  physics: const BouncingScrollPhysics(parent: AlwaysScrollableScrollPhysics()),
  slivers: <Widget>[
    CupertinoSliverRefreshControl(
      onRefresh: () {
        // loading new posts. I set state with blocBuilder but for easiness I show it with setState here:
        setState(() { posts = List.from(newPosts..addAll(posts)); })
      }
    ),
    SliverList(
      delegate: SliverChildBuilderDelegate((context, index) {
        return PostCard(posts[index]);
      },
      childCount: posts.length)
    )
  ]
);
final\u scrollController=scrollController(keepScrolOffset:true);
返回自定义滚动视图(
控制器:\ u滚动控制器
物理:常量反弹滚动物理(父项:AlwaysScrollableScrollPhysics()),
条子:[
铜控(
onRefresh:(){
//正在加载新帖子。我使用blocBuilder设置状态,但为了方便起见,我在此处使用setState显示:
setState((){posts=List.from(newPosts..addAll(posts));})
}
),
银表(
委托:SliverChildBuilderDelegate((上下文,索引){
返回明信片(帖子[索引]);
},
childCount:posts.length)
)
]
);
我的问题是什么 使用
ScrollController
保存
ScrollPosition
不起作用,因为它总是将偏移量保存到顶部而不是底部。在我的例子中,到顶部的偏移量将通过加载新的帖子而改变

我试过的 我还尝试在两个不同的
SliverLists
中构建旧帖子和新帖子。对于带有旧帖子的
SliverList
,我添加了一个键,并将我的
CustomScrollView
center
设置为此键。这样做会使我的
CupertinoSliverRefreshControl
崩溃

此外,我不能只使用反向列表,因为我希望在进一步开发状态下加载到另一个方向。

您可以使用:

//您需要将以下代码段放置在适当的位置。
双延伸器;
//从底部保存当前偏移:
extentAfter=\u scrollController.position.extentAfter;
//加载完成后,可以应用保存的extentAfter:
_scrollController.jumpTo(_scrollController.position.maxScrollExtent-extentAfter);
我不知道你的设置是如何工作的,但我可以想象,保存
extentAfter
可以在
ScrollController
的侦听器中完成(因为你想在插入新项目之前拥有最新的
extentAfter
),并在重建滚动视图时跳到“新建”位置

通过提供新的
滚动控制器进行重建时,您不能调用
跳到

//使用新位置更新滚动控制器。
_scrollController=scrollController(
initialScrollOffset:_scrollController.position.maxScrollExtent-extentAfter
);

尝试过,但效果并不理想。我必须在重建后调用_scrollController.jumpTo()。因此,在短时间内,它将跳到列表的顶部,然后立即返回到我的位置。跳转后的位置是正确的:)或指定我的注释:是否有方法在创建列表后立即调用jumpTo?好主意,但在重建之前不会更新\u scrollController.position.maxScrollExtent,因为它仍然被分配给旧列表。@Sonius在这种情况下,您必须计算新的值
maxScrollExtent
。如果你的物品有固定的尺寸,这应该是相当容易的。它们不是。但我想我可以用它,谢谢!你好@Sonius!两年后我和你在同一个地方。在使用控制器更新滚动时,您是否找到了避免跳跃式listview的方法?当你写
的时候,我发现自己和你完全处于同一个位置,所以在短时间内,它会跳到列表的顶部,然后回到我的位置。跳转后的位置正确
。谢谢