ehe*_*hhh 18 reverse android chat android-recyclerview linearlayoutmanager
我想用来RecyclerView
创建一个聊天应用程序.我使用的是LinearLayoutManager
用setReverseLayout(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
适配器中的方法.
如果您知道可以使用更改的项目,则在 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)
这只会重新绑定此范围内的视图