RecyclerView侧滑删除后重复添加最后一项问题求助
问题分析与解决方案
看起来你遇到的重复条目问题,根源在于数据源与UI不同步、文件操作逻辑错误这几个核心问题,我们一步步拆解并修复:
核心问题总结
- 每次启动Activity都会重建所有文件:
onCreate里的文件创建循环没有检查文件是否存在,导致删除的文件会被立刻重新生成。 - 侧滑删除未更新数据源:只调用了
notifyItemRemoved(position),但没有从recordingArrayList中移除对应元素,导致Adapter的数据源和UI状态不一致。 - 文件删除的文件名计算错误:用
position-1作为文件序号,比如第一个条目(position=0)会生成Recording-1.txt,根本无法删除正确的目标文件。 - 文件读取逻辑混乱:拼接所有文件内容再分割的方式,导致无法正确将单个文件内容对应到RecyclerView的条目。
修复后的完整代码与说明
1. 修复文件创建逻辑(仅在文件不存在时创建)
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my_recordings); // 仅当文件不存在时创建,避免删除后重建 for(int i=0;i<5;i++){ try{ userRecordingFile = new File(createRecordingFiles(), "Recording"+i+".txt"); if (!userRecordingFile.exists()) { FileWriter writer = new FileWriter(userRecordingFile); writer.append("DEF"+i+"__HIJ "+i+"__\n"); writer.flush(); writer.close(); } } catch (Exception e){ e.printStackTrace(); } } getSupportActionBar().hide(); recordingArrayList=new ArrayList<>(); recyclerView=findViewById(R.id.recyclerView); recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext())); recyclerView.setHasFixedSize(true); itemTouchHelper.attachToRecyclerView(recyclerView); // 读取文件内容到数据源 readFiles(); recordingsAdapter=new RecordingsAdapter(recordingArrayList); recyclerView.setAdapter(recordingsAdapter); }
2. 修复侧滑删除逻辑(同步数据源与文件操作)
ItemTouchHelper.SimpleCallback simpleItemTouchCallback = 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 swipeDir) { final int position = viewHolder.getAdapterPosition(); // 1. 先从数据源移除对应条目 recordingArrayList.remove(position); // 2. 通知Adapter更新UI recordingsAdapter.notifyItemRemoved(position); // 3. 删除对应的文件(position直接对应文件序号,无需减1) File workDir = new File(getExternalCacheDir(), USER_MIX_DIR); File file = new File(workDir, "Recording" + position + ".txt"); if (file.delete()) { Toast.makeText(getApplicationContext(), "Removed item " + (position+1), Toast.LENGTH_LONG).show(); } else { Toast.makeText(getApplicationContext(), "Failed to delete file", Toast.LENGTH_LONG).show(); // 删除失败时恢复条目,避免数据源与文件不一致 recordingArrayList.add(position, new Recording(R.drawable.ic_launcher, "DEF"+position, "HIJ "+position)); recordingsAdapter.notifyItemInserted(position); } } };
3. 修复文件读取逻辑(逐个解析文件内容)
public void readFiles(){ recordingArrayList.clear(); // 清空旧数据 File workDir = new File(getExternalCacheDir(), USER_MIX_DIR); for(int i=0;i<5;i++){ File file = new File(workDir,"Recording"+i+".txt"); if (!file.exists()) continue; // 跳过已删除的文件 BufferedReader br = null; try { br = new BufferedReader(new FileReader(file)); String line; while ((line = br.readLine()) != null) { String[] parts = line.split("__"); if (parts.length >= 2) { // 将单个文件内容解析为Recording对象,添加到数据源 recordingArrayList.add(new Recording(R.drawable.ic_launcher, parts[0].trim(), parts[1].trim())); } } } catch (IOException e) { e.printStackTrace(); } finally { if (br != null) { try { br.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
额外优化建议
- 如果未来文件数量不是固定5个,可以遍历目录下的所有
.txt文件,而不是固定循环5次,提升灵活性。 - 建议给
RecordingsAdapter添加更新数据源的方法,方便后续批量更新:public void updateData(ArrayList<Recording> newData) { mData.clear(); mData.addAll(newData); notifyDataSetChanged(); }
内容的提问来源于stack exchange,提问作者user8412632
相关产品推荐
相关产品推荐

