我有一个私人 ItemTouchHelper 从房间数据库中删除一行,但是目前当我滑动删除时它会导致 ArrayIndexOutOfBounds 异常:
FATAL EXCEPTION: main
Process: xxx.xxx.xxx.xxx, PID: 6327
java.lang.ArrayIndexOutOfBoundsException: length=1; index=-1
我已经发布了一个类似的问题,但是现在我已经提炼出问题的根源是 itemTouchHelper。
itemtouch 助手附加到一个 RecycleViewAdapter,它从房间数据库中获取它的数据集。
数据集显示为列表,我正在使用 itemTouchHelper 的 viewHolder.getAdapterPosition删除 RecycleAdapter 中已刷过的位置处的项目。这会引起我的问题吗?
我附上了相关代码:
mainActivity.java 中的数据库处理代码
@Override
public boolean searchTerm(String title) {
try {
this.dbThread.submit(() -> {
this.searchResults = this.userData.listModel().searchByTitle(title);
});
this.mRecycleAdapter.reloadAdapterData(this.searchResults);
this.mRecycleAdapter.notifyDataSetChanged();
Log.d(TAG, "Search Successful!");
return true;
} catch (Exception e) {
Log.d(TAG, "Search Failed \n -See Console");
return false;
}
}
@Override
public void addTask(GlobalLists item) {
this.dbThread.submit(() -> {
this.userData.listModel().insertItem(item);
});
}
@Override
public List<GlobalLists> getAllToDo() {
this.dbThread.submit(() -> {
this.searchResults = this.userData.listModel().loadAllLists();
});
return this.searchResults;
}
@Override
public List<GlobalLists> getResults() {
return this.searchResults;
}
@Override
public RecycleViewAdapter getAdapter() {
return this.mRecycleAdapter;
}
@Override
public void refresh() {
try {
this.dbThread.submit(() -> {
this.mRecycleAdapter.reloadAdapterData(this.userData.listModel().loadAllLists());
});
this.mRecycleAdapter.notifyDataSetChanged();
} catch (Exception e) {
Toast.makeText(this, "Refresh Failed", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
@Override
public void completeTask(GlobalLists item) {
try {
this.dbThread.submit(() -> {
this.userData.listModel().completeTask(new CompletedTasks(item.getTitle(), item.getContents()));
this.userData.listModel().deleteItem(item);
});
this.refresh();
Log.d(item.getTitle(), "Task Completed!");
} catch (Exception e) {
Toast.makeText(this, "Complete Task Failed", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
@Override
public void deleteTask(GlobalLists item) {
try {
this.dbThread.submit(() -> {
this.userData.listModel().deleteItem(item);
});
this.refresh();
Log.d(item.getTitle(), "Task Deleted");
} catch (Exception e) {
e.printStackTrace();
}
}
回收视图适配器
public class RecycleViewAdapter extends RecyclerView.Adapter<RecycleViewAdapter.ViewHolder>{
private LayoutInflater inflater = null;
private List<GlobalLists> results = null;
public RecycleViewAdapter(Context context, List<GlobalLists> results){
this.inflater = LayoutInflater.from(context);
this.results = results;
}
@NonNull
@Override
public RecycleViewAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.custom_row, parent, false);
ViewHolder holder = new ViewHolder(view);
return holder;
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
GlobalLists item = this.results.get(position);
holder.rowTitle.setText(item.getTitle());
}
public void reloadAdapterData(List<GlobalLists> refresh){
this.results = refresh;
}
@Override
public int getItemCount() {
return this.results == null ? 0 : this.results.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
private TextView rowTitle = null;
private ImageView rowImage = null;
private CheckBox completedCheck = null;
public ViewHolder(View itemView) {
super(itemView);
this.rowTitle = itemView.findViewById(R.id.rowTitle);
this.rowImage = itemView.findViewById(R.id.rowImage);
this.completedCheck = itemView.findViewById(R.id.completedCheck);
}
}
}
带有 itemTouchHelper 的片段
public class showAllLists_fragment extends android.support.v4.app.Fragment {
private static final String TAG = "showAllLists";
private RecyclerView mAllItemsView = null;
private DataCommunication mData = null; //interface for communicating between Activity and fragment.
private ItemTouchHelper itemTouchHelper = null;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View view = inflater.inflate(R.layout.show_all_lists_frag, container, false);
this.mAllItemsView = (RecyclerView) view.findViewById(R.id.allItems);
this.itemTouchHelper = new ItemTouchHelper(this.createHelperCallBack());
this.itemTouchHelper.attachToRecyclerView(this.mAllItemsView);
this.mAllItemsView.setAdapter(this.mData.getAdapter());
this.mAllItemsView.setLayoutManager(new LinearLayoutManager(getActivity()));
return view;
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
try {
this.mData = (DataCommunication) context;
} catch (ClassCastException e) {
throw new ClassCastException(context.toString()
+ " must implement DataCommunication");
}
}
private ItemTouchHelper.Callback createHelperCallBack() {
ItemTouchHelper.SimpleCallback simpleCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
if (direction == ItemTouchHelper.LEFT) {
mData.deleteTask(mData.getAllToDo().get(viewHolder.getAdapterPosition()));
mData.getAdapter().notifyItemRemoved(viewHolder.getAdapterPosition());
} else if (direction == ItemTouchHelper.RIGHT) {
mData.completeTask(mData.getAllToDo().get(viewHolder.getAdapterPosition()));
mData.getAdapter().notifyItemRemoved(viewHolder.getAdapterPosition());
}
}
};
return simpleCallback;
}
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
this.mData.refresh();
}
}
}
我从调试中注意到,一个项目需要 2 次滑动才能从 RecycleAdapter 的视图中完全消失,有时它不会删除我正在滑动的内容