I use this code to scroll:
WidgetsBinding.instance?.addPostFrameCallback((_) => _scrollToEnd());
_scrollToEnd()
method is:
_scrollController.animateTo(
_scrollController.position.maxScrollExtent,
duration: const Duration(
milliseconds: 200,
curve: Curves.easeInOut,
想象一下,这是一个普通的聊天屏幕。如果信息只有一行,它就会滚动到最下面。但是一旦信息达到2行以上,它就很难滚动到最底部。信息的行数越多,滚动到底部的次数就越少。
这就是我进入聊天室时的样子。
但如果我进一步向下滚动,这就是聊天的底部。
我注意到还有一种情况,那就是。
I enter the chat.
It scrolls down like on the first image.
If i tap anywhere on the screen, it continues to scroll to the bare bottom of the listview like on the second image.
为什么会发生这种情况,我怎样才能解决这个问题?
7 个回答
0 人赞同
我所做的是,使用一个listView和反向的true,并在儿童中使用map.reversed的列表,我在下面给你我的代码例子。
ListView(
reverse: true,
children: controller.listMessageData.reversed
.map((e) => Container(child: Text(e.title));
0 人赞同
只是一个变通方法,但它应该能像预期那样工作。在列表视图中使用夹持物理学。在最大范围内添加一个额外的数字
_scrollController.animateTo(
_scrollController.position.maxScrollExtent+300,
duration: const Duration(
milliseconds: 200,
curve: Curves.easeInOut,
0 人赞同
使用ScrollController吧,它工作起来很顺畅,使用起来很简单。
ScrollController _scrollController = new ScrollController();
像这样给LisView添加控制器。
ListView.builder(controller: _scrollController,)
在你的initState中,当导航到这个屏幕时要滚动到底部
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
if (_scrollController.hasClients) {
_scrollController.animateTo(
_scrollController.position.maxScrollExtent,
curve: Curves.easeOut,
duration: const Duration(milliseconds: 500),
0 人赞同
我终于找到了一个解决方案。没有一个答案对我有用,或部分有用,但我很感谢你试图回答。
对我来说,我所要做的就是把
reverse: true
在ListView构建器中,然后每当你返回信息时,你需要以如下方式返回。
return messages[messages.length - 1 - index];
这是最重要的部分。
0 人赞同
Use should use the reverse property.
ListView.builder(
reverse: true,
itemCount: 10,
itemBuilder: (_, index) {
return ListTile(title: Text(index.toString()));
0 人赞同
当我不得不在项目展开时为其添加滚动时,我也遇到了类似的问题。
我的猜测是,你在向列表中添加新元素时,在相同的构建中调用animate to,所以最大的滚动范围在元素的渲染后发生了变化,你滚动到了前一个元素,或者类似的东西。
the code goes like this:
static const int tickCount = 8;
int i = 0;
Future<void> _scrollToEnd() async {
if (mounted && tickCount > i) {
final ScrollPosition position = Scrollable.of(context).position;
final double target = position.pixels +
(position.maxScrollExtent - position.pixels) / (tickCount - i);
position.moveTo(
target,
duration: duration,
curve: Curves.linear,
await Future.delayed(duration);
WidgetsBinding.instance.addPostFrameCallback((_) => _scrollToItem());
并在第一次发射时重置我的状态。
WidgetsBinding.instance.addPostFrameCallback((_) {
i = 0;
_scrollToItem();
代码有点乱,但我希望能有帮助。
0 人赞同
这里有一个解决方案,可以一直向下滚动到最后,而不用手工添加任何额外的像素。唯一的缺点是,你只能使用Curves.linear
作为动画。
Future.doWhile(() {
if (scrollController.position.extentAfter == 0)
return Future.value(false);
return scrollController