如何使具有正常转录模式的Listview顺畅地向下滚动?

How to make Listview with normal transcript mode scrolls down smoothly?

我有一个 ListView 用于聊天。 当新消息出现时,我需要自动向下滚动该列表。我用

做到了
chatView.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_NORMAL);

一切都很顺利,但我希望列表能够顺畅地向下滚动,就像使用 smoothScrollBy() 方法一样。现在它只是在调用 notifyDataSetChanger() 时跳到最后。

我怎样才能做到这一点? 这是我的 ListView xml 项,以防万一:

 <ListView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:stackFromBottom="true"
        android:clipToPadding="false"
        android:divider="@null" android:dividerHeight="4dp"
        android:id="@+id/chat" 
        android:layout_weight="1"
        android:background="@color/background_green"
        android:paddingBottom="@dimen/between_elements_spacing"/>

你试过用这个吗

list.smoothScrollToPosition(postitionOfRow);

如果使用正确,notifyData 不应在任何地方滚动。你能post你这样做的代码吗?

我觉得转录模式没有 "animated" 选项有点令人沮丧。实现这一点的方法是禁用转录模式,并在调用 notifyDataSetChanged():

if (determineIfListViewShouldAutoScroll()) {
    mainThreadHandler.post(() -> {
        listView.setSelection(adapter.getCount() - 2);
    });
    mainThreadHandler.post(() -> {
        listView.smoothScrollToPosition(adapter.getCount());
    });
}

由于您已禁用转录模式,现在您需要创建一个 determineIfListViewShouldAutoScroll() 函数来确定是否执行任何操作。使用 chatListView.getLastVisiblePosition() 确定列表视图是否滚动到足以自动显示新项目的程度。对于类似于转录模式 "normal" 的内容,您只需检查最后一个可见项目的位置是否在项目总数的 1 或 2 以内。

这不会让您对动画有任何控制,列表视图会做任何它想做的事。如果您需要更多控制,您可以运行每个刻度调用的自定义动画listView.setSelectionFromTop(lastItemPosition, listviewHeight - distanceY);,其中listviewHeight是整个列表视图的高度,distanceY是动画值在 0 和新视图的测量高度之间。