【发布时间】:2019-08-18 19:24:19
【问题描述】:
我有从 sqlite 获取数据到 recyclerview 的应用程序。提供给 recyclerview 的功能是,recyclerview 的项目可以拖放和在交换时删除项目。拖放后,我正在删除整个数据库表并存储新数组,该数组包含拖放后更新顺序的项目。在通过交换删除项目后,我也在做同样的删除和存储东西。交换后删除项目时出现问题,我通过在拖放事件后重置适配器项目(通过使用notifyDataSetChanged())解决了该问题,以便在删除时新的项目位置列表可用。
现在来看看当前的问题是:
为了检查是否发生拖放事件,我在一个干扰中使用标志(布尔),该接口仅在发生拖放事件时调用。因此,如果该事件为真,则删除数据并将新列表存储在数据库中并调用notifyDataSetChanged()。问题是,如果我拖放单个项目,该标志返回 true,因为调用了 notifyDataSetChanged(),所以如果用户想在他不能拖动的两个或三个项目之后拖动项目,我不能拖动项目位置超过一个。
那么在所有拖放事件完成后我可以使用notifyDataSetChanged吗,目前只能拖动一个位置。
适配器内用于拖放内容的代码。
@Override
public boolean onItemMove(int fromPosition, int toPosition) {
if (fromPosition < toPosition) {
for (int i = fromPosition; i < toPosition; i++) {
Collections.swap(customDataListModels, i, i + 1);
}
Log.e("UpTODown", String.valueOf(toPosition));
} else {
for (int i = fromPosition; i > toPosition; i--) {
Collections.swap(customDataListModels, i, i - 1);
}
Log.e("DownToUp", String.valueOf(toPosition));
}
Log.e("postion", "from pos : "+String.valueOf(fromPosition)+" : to Position :"+String.valueOf(toPosition));
mListChangedListener.onNoteListChanged(customDataListModels);
notifyItemMoved(fromPosition, toPosition);
chCustom=customDataListModels;
if (swapChecker == true) {
tempSqliteDatabaseHelper.deleteall();
for (int i = 0; i < chCustom.size(); i++) {
Log.e("PositionInSwap", String.valueOf(chCustom.get(i).getName()));
tempinsert(chCustom.get(i).getName(), chCustom.get(i).getNumber(), chCustom.get(i).getColor(), chCustom.get(i).getFSize(), 1);
}
notifyDataSetChanged();
}
return true;
}
在上面的代码中,swapChecker == true 在拖放事件发生时为真。
@Override
public void onNoteListChanged(List<CustomDataListModel> customDataListModels) {
swapChecker = true;
}
tempinsert 方法正在存储到数据库中。如果您对代码感到好奇,那么这与当前问题完全无关:
public void tempinsert(String name, String num, String color, int size, int index) {
boolean inSamedata = tempSqliteDatabaseHelper.IsItemExist(name, num);
if (inSamedata == false) {
boolean indata = tempSqliteDatabaseHelper.insertData(new ContactModel(name, num, color, size, index));
if (indata == true) {
Log.e("DataSave", "DataSave");
} else {
Log.e("In_Data_not_True", "In Data not True");
}
} else if (inSamedata == true) {
Log.e("Record_Exist", "Record Exist");
}
}
在适配器中实现的接口:
public class CustomRecycleAdapter extends RecyclerView.Adapter<CustomRecycleAdapter.MyContactHolder> implements ItemTouchHelperAdapter{
}
public interface ItemTouchHelperAdapter {
}
void onRowSelected(CustomRecycleAdapter.MyContactHolder myViewHolder);
void onRowClear(CustomRecycleAdapter.MyContactHolder myViewHolder);
boolean onItemMove(int fromPosition, int toPosition);
}
在继承自 ItemTouchHelper.Callback 类的 SimpleItemTouchHelperCallback 类的 onMove 方法中调用 onItemMove
public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callback {
private final ItemTouchHelperAdapter mAdapter;
public SimpleItemTouchHelperCallback(ItemTouchHelperAdapter adapter) {
mAdapter = adapter;
}
@Override
public boolean isLongPressDragEnabled() {
return true;
}
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
return makeMovementFlags(dragFlags, 0);
}
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder,
RecyclerView.ViewHolder target) {
mAdapter.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());
return true;
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
}
}
我发布了接口代码和它下面的代码,因为一些用户建议我使用 onRowSelected 和 onRowClear 覆盖方法。但我注意到我不能直接使用这些方法。所以我从接口中提取这些方法。
【问题讨论】:
标签: android sqlite drag-and-drop android-recyclerview