Dom*_*ník 7 flutter flutter-listview
我正在尝试构建列表,您可以在其中添加有限的项目(因此两侧不是无限的)。在顶部,您将进行刷新,它将加载新项目,但您将停留在同一位置(新项目位于您当前位置的顶部)。在底部你会加载更多但相同的,留在同一个地方。我尝试过使用 CustomScrollView 和两个带中心的条子来执行此操作,但我想做的是在刷新时我想删除一些旧项目,发生的情况是它跳转到新的中心并刷新卡片。就是上面那个点。
当前状态
CustomScrollView(
physics: const BouncingScrollPhysics(
parent: AlwaysScrollableScrollPhysics(),
),
center: _mainListKey,
controller: scrollController,
cacheExtent: 1000,
slivers: <Widget>[
SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return ComplexWidget(item: topItems[index]),
},
childCount: topItems.count,
),),
SliverList(
key: _mainListKey
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return ComplexWidget(item: bottomItems[index]),
},
childCount: bottomItems.count,
),),
]
),
Run Code Online (Sandbox Code Playgroud)
更好的行为描述:
好吧,想象一下 Twitter 应用程序中的相同列表。如果你向下滚动,它将加载越来越多、越来越旧的推文。有时,它会加载后台较新的项目,这些项目会加载到顶部,而不会让您滚动。最后,您可以转到顶部并拉动刷新,它将下载新项目(Twitter 中存在差异),并将项目添加到您的位置之上。
所以有3个触发器:
其中任何人都不应该让你改变立场
我已经设法 fork oscrollable_positioned_list 到,不需要跳过 itemScrollControlled 。
我已向scrollable_positioned_list添加了两个参数
final bool keepPosition;
final String Function(int index)? onItemKey;
Run Code Online (Sandbox Code Playgroud)
在构建时我添加了
if (widget.itemCount > 0 && widget.onItemKey != null) {
_lastTargetKey = widget.onItemKey!(primary.target);
} else {
_lastTargetKey = null;
}
Run Code Online (Sandbox Code Playgroud)
额外搜索索引
String? _lastTargetKey;
int? _getIndexOfKey() {
if (widget.onItemKey != null) {
int? index;
for (var i = 0; i < widget.itemCount; i++) {
if (widget.onItemKey!(i) == _lastTargetKey) {
index = i;
break;
}
}
return index;
}
}
Run Code Online (Sandbox Code Playgroud)
并添加到didUpdateWidget
if (widget.keepPosition) {
if (_lastTargetKey != null) {
var foundIndex = _getIndexOfKey();
if (foundIndex != null && foundIndex > primary.target) {
primary.target = foundIndex;
}
}
}
Run Code Online (Sandbox Code Playgroud)