android - 在 Android 中滚动时如何坚持适配器位置?
问题描述
问题是,在我的 recyclerview - 适配器中,单击删除按钮,我显示小进度条代替删除按钮。现在假设完成删除过程需要 2 分钟。因此,与此同时,如果用户正在滚动 recyclerview,则正在运行的进度条会交换 position。
我怎么能控制它?
流程:单击删除-delete.onClicklistener-在侦听器内部-在活动中通知-调用异步任务-异步任务结果侦听器是onDeleteDataReceived-在适配器类中调用 updateView()-在 updateView() 内部更改可见性。
注意:该特定位置的项目被正确删除,但在滚动回收视图时进度条位置交换
我已经检查了这个答案,但在我的情况下不起作用:为什么 EditText 中的输入值在 RecyclerView 中滚动时会交换其位置?
代码:
适配器类:
public void updateView(int position, RecyclerView.ViewHolder viewHolder) {
try {
if (viewHolder.getAdapterPosition() == position) {
MyViewHolder holder = (MyViewHolder) viewHolder;
holder.delete.setVisibility(View.VISIBLE);
holder.progressBar.setVisibility(View.GONE);
notifyItemRemoved(position);
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {
Events events = eventList.get(position);
holder.delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (listener != null) {
holder.delete.setVisibility(View.GONE);
holder.progressBar.setVisibility(View.VISIBLE);
eventList.get(position).isSelected = true;
listener.onClicked(position, eventList.get(position).getEventId());
}
}
});
活动:
@Override
public void onDeleteDataReceived(Boolean status, int position) {
stopShimmerLayout();
if (status) {
try {
if (eventsList.get(position).isSelected) {
eventsList.remove(position);
RecyclerView.ViewHolder viewHolder = recyclerView.findViewHolderForAdapterPosition(position);
mAdapter.updateView(position, viewHolder);
}
} catch (Exception e) {
e.printStackTrace();
}
} else {
showToast(context, "Failed", Toast.LENGTH_SHORT);
}
}
观看视频以获得更好的理解:https ://drive.google.com/open?id=13ZAtnyfGbi2X4JjUTmJsIDy-gt5y51Gr
实施:https ://drive.google.com/open?id=1ePOfZctEO_IhzUM3bFYW3VJKThoVkI6a
这是什么? 为什么每个人都在说同样的事情?我要问的是一切正常。我能够显示正确位置的进度条和删除按钮可见性,并且项目也被用户选择的位置正确删除。问题是在删除时,如果我开始快速滚动,那么运行进度条会交换位置。但是当我再次到达那个位置时,那个项目被删除了。
解决方案
我认为这是在RecyclerView
. 一个简单的修复可能是保存当前正在删除的项目的位置,并onBindViewHolder
根据您存储的位置设置进度微调器。
让我们在类中采用一个额外的变量,Event
如此处其他答案中所指出的那样。这是为了跟踪项目删除。
public class Event {
// ... Your other variables will go here
public boolean isDeleting = false; // Set the default value to false
}
现在在onClickListener
ofdelete
按钮中,更新变量的状态以指示项目是否正在被删除。
@Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {
Events events = eventList.get(position);
holder.delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (listener != null) {
// We do not need setting the visibility here. The next actions for notifyDataSetChanged will take care of this.
// holder.delete.setVisibility(View.GONE);
// holder.progressBar.setVisibility(View.VISIBLE);
eventList.get(position).isSelected = true;
eventList.get(position).isDeleting = true; // Set the variable to true to indicate that the item is being deleted
listener.onClicked(position, eventList.get(position).getEventId());
// It is important here to notify the list that the views are changed when the delete button is clicked. Hence call the notifyDataSetChanged
notifyDataSetChanged();
}
}
});
// Now let us update the views based on the selection for deletion
if (eventList.get(position).isDeleting) {
// The item is being deleted
holder.progressBar.setVisibility(View.VISIBLE);
holder.delete.setVisibility(View.GONE);
} else {
// The item is not being deleted (normal case)
holder.progressBar.setVisibility(View.GONE);
holder.delete.setVisibility(View.VISIBLE);
}
}
现在从updateView
函数中,您需要根据需要设置并再次eventList
调用以在.notifyDataSetChanged
RecyclerView
public void updateView(int position) {
// Update the eventList
eventList.remove(position); // Remove the item that was deleted by the index
// Now let the RecyclerView know that the list is updated as one of the items is removed.
notifyDataSetChanged();
}
你应该很高兴去!
更新
我无法运行您共享的程序。但是,我有机会研究活动和适配器类。看起来这里还有其他一些问题。
这eventList
是一个ArrayList
不是线程安全的数据结构。您正在尝试删除后台线程中的事件并RecyclerView
在该线程上完成删除时更新。因此,当您尝试同时删除多个项目时,您无法真正确保列表会相应更新。
您可能会考虑synchronized
删除或使用线程安全的数据结构来避免eventList
.
推荐阅读
- magento - Magento 1.4 删除所有产品图片
- python - pyqt :向用户显示 QListWidget 中存在的所有值
- java - 多部分请求无法按预期进行弹簧集成
- java - 使用 XSSFWorkbook 创建 xlsx 文件,但使用方法 createSheet("String") 时出错
- python - Python 3 使用 Bs4 抓取
- oracle - 使用 Oracle DBMS_DATAPUMP 导入单个表时主表出错
- python - 仅在相同的索引值内识别列值的变化
- xml - 将 XML 数据导入 MS Access 运行时错误
- soap - 什么是 Servicenow SOAP API getkeys 通配符?
- c++ - 使用新值和值但没有明确数量的元素的数组初始化