颤动 ListView 滚动到索引不可用
Posted
技术标签:
【中文标题】颤动 ListView 滚动到索引不可用【英文标题】:flutter ListView scroll to index not available 【发布时间】:2019-05-31 01:39:56 【问题描述】:我需要什么:
我想按某个索引滚动列表,我该怎么做。
我所知道的:
scrollToIndex
应该从第 n 个索引开始,但是我们如何滚动到任何索引?
【问题讨论】:
试试indexed_list_view。 查看我写的这篇文章:medium.com/@diegoveloper/… @JeromeEscalante 我已经检查了 indexex_list_view 但它是无限列表我的列表来自数据库并且大小将是动态的。 @diegoveloper 我也检查了你的帖子,但在我的情况下,列表项大小不固定。 你也可以试试这个:github.com/quire-io/scroll-to-index 【参考方案1】:不幸的是,ListView 没有内置的 scrollToIndex() 函数方法。您必须开发自己的方法来测量该元素对 animateTo()
或 jumpTo()
的偏移量,或者您可以搜索这些建议的解决方案/插件或从其他帖子中搜索,例如 Flutter: Scrolling to a widget in ListView
(自 2017 年以来,flutter/issues/12319 讨论了一般的 scrollToIndex 问题,但目前还没有计划)
但是有一种不同类型的 ListView 确实支持 scrollToIndex(Slashbin 提到过):
ScrollablePositionedList 依赖:scrollable_positioned_list您的设置与 ListView 完全一样,并且工作方式相同,只是您现在可以访问 ItemScrollController:
jumpTo(index, alignment)
scrollTo(index, alignment, duration, curve)
简化示例:
ItemScrollController _scrollController = ItemScrollController();
ScrollablePositionedList.builder(
itemScrollController: _scrollController,
itemCount: _myList.length,
itemBuilder: (context, index)
return _myList[index];
,
)
_scrollController.scrollTo(index: 150, duration: Duration(seconds: 1));
(请注意,此库由 Google 开发,而非 Flutter 核心团队开发。)
【讨论】:
很棒的答案。虽然我注意到当index == item.length - 1
时,scrollController 的行为很有趣。可能是因为我用了BouncingScrollPhysics()
ScrollablePositionedList 的缺点是它与增量滚动要求不兼容(例如响应向上/向下箭头键),因为它的 API 确实涉及偏移量(甚至是相对偏移量)。
但是我不能为ScrollablePositionedList设置控制器键,如果你想做更多的事情就不好了【参考方案2】:
ScrollablePositionedList
可以用于此。
https://github.com/google/flutter.widgets/tree/master/packages/scrollable_positioned_list
Pub link - https://pub.dev/packages/scrollable_positioned_list
final ItemScrollController itemScrollController = ItemScrollController();
final ItemPositionsListener itemPositionListener = ItemPositionsListener.create();
ScrollablePositionedList.builder(
itemCount: 500,
itemBuilder: (context, index) => Text('Item $index'),
itemScrollController: itemScrollController,
itemPositionsListener: itemPositionListener,
);
然后可以通过以下方式滚动到特定项目:
itemScrollController.scrollTo(
index: 150,
duration: Duration(seconds: 2),
curve: Curves.easeInOutCubic);
【讨论】:
【参考方案3】:使用scroll_to_index
lib,这里滚动总是执行到第六个位置,如下面的硬编码
dependencies:
scroll_to_index: ^1.0.6
代码片段:
class MyHomePage extends StatefulWidget
MyHomePage(Key key, this.title) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
class _MyHomePageState extends State<MyHomePage>
final scrollDirection = Axis.vertical;
AutoScrollController controller;
List<List<int>> randomList;
@override
void initState()
super.initState();
controller = AutoScrollController(
viewportBoundaryGetter: () =>
Rect.fromLTRB(0, 0, 0, MediaQuery.of(context).padding.bottom),
axis: scrollDirection);
@override
Widget build(BuildContext context)
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: ListView(
scrollDirection: scrollDirection,
controller: controller,
children: <Widget>[
...List.generate(20, (index)
return AutoScrollTag(
key: ValueKey(index),
controller: controller,
index: index,
child: Container(
height: 100,
color: Colors.red,
margin: EdgeInsets.all(10),
child: Center(child: Text('index: $index')),
),
highlightColor: Colors.black.withOpacity(0.1),
);
),
],
),
floatingActionButton: FloatingActionButton(
onPressed: _scrollToIndex,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
// Scroll listview to the sixth item of list, scrollling is dependent on this number
Future _scrollToIndex() async
await controller.scrollToIndex(6, preferPosition: AutoScrollPosition.begin);
输出:
【讨论】:
【参考方案4】:如果您知道 listview 项目大小,则滚动到首选索引很简单,例如:
var index = 15;
var widthOfItem =
176; //in dp. width needed for horizontallistView;
var heightOfItem =
200; //in dp. height need for vertical listView;
listViewScrollController.jumpTo(index * widthOfItem.toDouble());
或
listViewScrollController.animateTo(
index * widthOfItem.toDouble(),
duration: Duration(milliseconds: 500),
curve: Curves.ease);
【讨论】:
【参考方案5】:找到一个 gist,其工作 gist url 是 https://gist.github.com/debuggerx01/b8ef756ee02b3eb82ec3702f14ba94e6
这个要点正在使用一个计算矩形大小的包。 https://pub.dartlang.org/packages/rect_getter
【讨论】:
是的,它可以工作,但看起来我的列表视图中带有 cmets 的 FPS 变得非常低.. 操作太多。 如果我使用 ListView.builder 是否可以使用此解决方案?以上是关于颤动 ListView 滚动到索引不可用的主要内容,如果未能解决你的问题,请参考以下文章