android - 带有项目插入的 RecyclerView 无限滚动
问题描述
我有一个难题,我也有解释它的问题,所以请耐心等待
我有一个无限滚动 RecyclerView
(只从上到下)。
这RecyclerView
显示了电话从第一条到最后一条收到的消息,当到达最后一条时,它再次显示第一条(仅向下滚动)等等。
我使用自动滚动功能实现了这个解决方案,该功能总是增加我的位置以平滑滚动到下一个显示。在适配器中,我获取列表中项目的实际位置并将其绑定到我的视图(即:如果我有 2 个项目,并且要显示的位置是第 5 个,我将获得第一个项目的逻辑以这种方式显示项目:1-2-1-2-1)。
我的问题是一切正常,但是当在滚动期间将新项目添加到数据源并调用 时NotifyDataSetChangd
,一切都会刷新,我的列表会闪烁,更改当前显示的项目。
我试着用一个例子来解释这个问题:假设我当前的可见索引是我无限滚动中的第 5 个,并且我的源有 2 个项目。
正如您在“之前”列中看到的那样,在可见索引 5 处,我将看到 B 项。
现在一条消息到达,并且通知源更新了所有内容。
位置 -- 之前 -- 之后
0 A A
1 B B
2 A C
3 B A
4 A B
5 B C
6 A A
7 B B
8 A C
9 B A
现在出现的情况:列表闪烁并显示项目 C(后列的索引 5)。
我想要的是:列表应该像现在一样继续,在实际 AB 旋转之后,它会显示新添加的 C 项目,而不会闪烁和刷新所有内容。
这是适配器(或多或少它完成了所有工作,我认为它是唯一重要的代码)
import android.graphics.Typeface;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.Map;
import utilitapps.com.ememories.R;
import utilitapps.com.ememories.db_objects.SMSMessage;
public class MessagesAdapter extends RecyclerView.Adapter<MessagesAdapter.MessagesViewHolder> {
private ArrayList<SMSMessage> SMSMessages;
private int textSize;
private Typeface custom_font;
private int lastShownPosition;
LinkedHashMap<Integer, Integer> offsets;
Integer lastEntryKey;
public MessagesAdapter(int textSize, Typeface custom_font, ArrayList<SMSMessage> SMSMessages) {
this.SMSMessages = SMSMessages;
this.textSize = textSize;
this.custom_font = custom_font;
this.lastShownPosition = 0;
this.offsets = new LinkedHashMap<>();
offsets.put(0, -1);
}
public void addItem(SMSMessage msg) {
SMSMessages.add(msg);
if (SMSMessages.size() > 1) {
offsets.remove(lastEntryKey);
offsets.put(lastEntryKey, lastShownPosition);
//aggiungo poi l'ultima
lastEntryKey = lastShownPosition + 1;
offsets.put(lastEntryKey, -1);
} else {
}
notifyDataSetChanged();
}
public int getActualItemCount() {
if (SMSMessages == null) {
SMSMessages = new ArrayList<>();
}
return SMSMessages.size();
}
@Override
public int getItemCount() {
return Integer.MAX_VALUE;
}
@NonNull
@Override
public MessagesAdapter.MessagesViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new MessagesAdapter.MessagesViewHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.recyclerview_item_message, parent, false));
}
@Override
public void onBindViewHolder(@NonNull MessagesAdapter.MessagesViewHolder holder, int position) {
lastShownPosition = position;
holder.bind(getSMSMessage(position));
}
private SMSMessage getSMSMessage(int position) {
if (SMSMessages.size() == 0) {
return null;
}
int itemLastIndex = 1;
for (Map.Entry<Integer, Integer> entry :
offsets.entrySet()) {
if (entry.getValue() == -1) {
return SMSMessages.get(position % SMSMessages.size());
}
if (position >= entry.getKey() && position <= entry.getValue()) {
return SMSMessages.subList(0, itemLastIndex).get(position % SMSMessages.subList(0, itemLastIndex).size());
}
itemLastIndex++;
}
return null;
}
class MessagesViewHolder extends RecyclerView.ViewHolder {
TextView tvMsgText;
MessagesViewHolder(View itemView) {
super(itemView);
tvMsgText = itemView.findViewById(R.id.tvMsgText);
tvMsgText.setTextSize(textSize);
tvMsgText.setTypeface(custom_font);
}
void bind(SMSMessage SMSMessage) {
if (SMSMessage != null && SMSMessage.isValid()) {
try {
tvMsgText.setText(SMSMessage.getMessageText());
} catch (Exception ignored) {
tvMsgText.setText("");
}
} else {
tvMsgText.setText("");
}
}
}
}
如您所见,我尝试实现一个存储索引映射的解决方案,因此我可以用这个示例填充我的列表(遵循以下逻辑:ABAB(已添加项目但已加载 A)ABCAB C ...)但它不起作用,我我不完全理解为什么。
我尽量说清楚,如果不是随便问
感谢帮助
我也对新方法持开放态度,这是我使用的方法,但可能是错误的,我真的不知道
解决方案
推荐阅读
- shell - 从 shell 脚本运行时出现 cURL 错误,但从终端运行时运行良好
- mysql - 更新 MySQL 中的桥实体
- php - PSR-2 的回车是否正确?
- webpack - 从 webpack-cli 获取错误:TypeError: merge.smart is not a function
- r-markdown - R Markdown - 无法在路径中找到图像
- javascript - React 忽略 shouldComponentUpdate() 中的 props 更改
- c# - 使用 DataTable 填充 MsAccess 表
- cron - 工作日和周末的不同时间表
- java - 向用户发送自动电子邮件
- python - 使用数据类型将固定分隔文件导入 Pandas