RecyclerView在插入时滚动

ehe*_*hhh 18 reverse android chat android-recyclerview linearlayoutmanager

我想用来RecyclerView创建一个聊天应用程序.我使用的是LinearLayoutManagersetReverseLayout(true).

当我一直滚动到底部(这是数据集start =最新消息)并且新消息被插入到数据集中时,该项目按预期显示在列表的底部(视图向上滚动以腾出空间)对于新项目).

我遇到的问题是当我向上滚动以查看较旧的消息时.当新消息插入到数据集的开头时,视图向上滚动大约一个消息高度,即使该消息甚至没有呈现,因为它超出了视口的范围.

当视图滚动到底部时,如何保持滚动行为,但在滚动到较旧的消息时禁用它?

更新: 我还制作了一个小应用程序,重现了这个问题:https: //github.com/ehehhh/RecyclerViewProblem

更新2:我提交的修复工作也适用于我制作的回购.

相关代码(希望如此):

compile 'com.android.support:recyclerview-v7:24.2.0'
Run Code Online (Sandbox Code Playgroud)

XML:

<android.support.v7.widget.RecyclerView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:clipToPadding="false"
            android:paddingBottom="8dp"
            android:paddingTop="8dp"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
Run Code Online (Sandbox Code Playgroud)

RecyclerView初始化代码:

layoutManager = new LinearLayoutManager(context);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
layoutManager.setReverseLayout(true);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setScrollContainer(true);
recyclerView.setLayoutAnimation(null);
recyclerView.setItemAnimator(null);
adapter = new ChatAdapter(...);
recyclerView.setAdapter(adapter);
Run Code Online (Sandbox Code Playgroud)

适配器:

public class ChatAdapter extends RecyclerView.Adapter<ChatViewHolder> {

    private List<MessageWrapper> dataset;

    public ChatAdapter(List<MessageWrapper> dataset, ...) {
        this.dataset = dataset;
        setHasStableIds(true);
    }

    ...

    @Override
    public long getItemId(int position) {
        return dataset.get(position).getId();
    }

    @Override
    public int getItemCount() {
        return dataset.size();
    }

    public void datasetChanged(List<MessageWrapper> dataset) {
        this.dataset = dataset;
        notifyDataSetChanged();
    }
}
Run Code Online (Sandbox Code Playgroud)

将新项添加到数据集时,我只需调用datasetChanged适配器中的方法.

Hal*_*a.M 6

如果您知道可以使用更改的项目,则在 Recycler 视图中使用 notifyDataSetChanged 是多余的

notifyItemInserted(position) 
Run Code Online (Sandbox Code Playgroud)

在这种特殊情况下,有效的是

 notifyItemInserted(0);
Run Code Online (Sandbox Code Playgroud)

或者

 notifyItemRangeInserted(positionStart, newItems.size() - 1)
Run Code Online (Sandbox Code Playgroud)

这只会重新绑定此范围内的视图

检查 https://developer.android.com/reference/android/support/v7/widget/RecyclerView.Adapter.html#notifyItemInserted(int)

  • 我玩了我创建的测试应用程序,它似乎与 `notifyItemInserted(0)` 一起工作,我将你的答案标记为正确的答案。谢谢! (2认同)