为什么我点击删除多个文件时,只有一个文件被删除?
Why is only one file getting deleted when I click to delete multiple?
我正在尝试制作一个程序,在其中列出 recyclerview 中的文件名。使用行内的按钮,应用程序应通过存储在包含文件路径的数组中的路径删除项目。如果在 toast 消息中单击卡片本身,应用程序还应显示文件路径。
到目前为止,我可以执行此操作,但是当应用程序处于活动状态时,我一次只能删除一个文件。当我尝试删除多个文件时出现问题。这些项目从 recyclerview 中删除,一切看起来都很正常,但是如果应用程序关闭,那么我在第一个文件之后尝试删除的文件再次出现,表明它们没有被删除。
我的代码:
JAVA 类
FileView.java(这是主activity)
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.widget.Toast;
import java.io.File;
import java.util.ArrayList;
public class FileView extends AppCompatActivity {
private RecyclerView fileRecyclerView;
private RowAdapter fileAdapter;
private RecyclerView.LayoutManager fileLayoutManager;
private ArrayList<RowItem> rowItem;
File[] fileList;
String filePath = "";
String fileData = "";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_file_view);
filePath = "PDF_files";
File file = new File(getExternalFilesDir(filePath).toString());
fileList = file.listFiles();
createRows();
buildRecyclerView();
}
public void createRows(){
rowItem = new ArrayList<>();
for (int i = 0; i < fileList.length; i++) {
rowItem.add(new RowItem(R.drawable.ic_book,(fileList[i].getName().replace("__", " ").replace('_','\n').replace('-','/').replace(".pdf",""))));
}
}
public void removeItem(int position) {
rowItem.remove(position);
fileAdapter.notifyItemRemoved(position);
}
public void buildRecyclerView() {
fileRecyclerView = findViewById(R.id.recyclerView);
fileRecyclerView.setHasFixedSize(true);
fileLayoutManager = new LinearLayoutManager(this);
fileAdapter = new RowAdapter(rowItem);
fileRecyclerView.setLayoutManager(fileLayoutManager);
fileRecyclerView.setAdapter(fileAdapter);
fileAdapter.setOnItemClickListener(new RowAdapter.OnItemClickListener() {
@Override
public void onItemClick(int position) {
fileData = fileList[position].toString();
Toast.makeText(FileView.this,"Clicked: " + fileData , Toast.LENGTH_SHORT).show();
}
@Override
public void onDeleteClick(int position) {
removeItem(position);
File deletePath = fileList[position];
deletePath.delete();
if(deletePath.exists()){
getApplicationContext().deleteFile(deletePath.getName());
}
}
});
}
}
RowAdapter.java(这是适配器class)
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class RowAdapter extends RecyclerView.Adapter<RowAdapter.RowViewHolder> {
private ArrayList<RowItem> mRowList;
private OnItemClickListener mListener;
public interface OnItemClickListener{
void onItemClick(int position);
void onDeleteClick(int position);
}
public void setOnItemClickListener(OnItemClickListener listener){
mListener = listener;
}
public static class RowViewHolder extends RecyclerView.ViewHolder{
public ImageView rowImageView;
public TextView rowTextView;
public ImageView rowDeleteImage;
public RowViewHolder(@NonNull View itemView, OnItemClickListener listener) {
super(itemView);
rowImageView = itemView.findViewById(R.id.fileImage);
rowTextView = itemView.findViewById(R.id.fileName);
rowDeleteImage = itemView.findViewById(R.id.deleteFile);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(listener != null){
int position = getAdapterPosition();
if(position != RecyclerView.NO_POSITION){
listener.onItemClick(position);
}
}
}
});
rowDeleteImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(listener != null){
int position = getAdapterPosition();
if(position != RecyclerView.NO_POSITION){
listener.onDeleteClick(position);
}
}
}
});
}
}
public RowAdapter(ArrayList<RowItem> rowList){
mRowList = rowList;
}
@NonNull
@Override
public RowViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.row, parent, false);
RowViewHolder rvh = new RowViewHolder(v, mListener);
return rvh;
}
@Override
public void onBindViewHolder(@NonNull RowViewHolder holder, int position) {
RowItem currentItem = mRowList.get(position);
holder.rowImageView.setImageResource(currentItem.getImageResource());
holder.rowTextView.setText(currentItem.getFileName());
}
@Override
public int getItemCount() {
return mRowList.size();
}
}
RowItem.java(图像和文件名的获取器)
public class RowItem {
private int imageResource;
private String fileName;
public RowItem(int img, String stringInput) {
this.imageResource = img;
this.fileName = stringInput;
}
public int getImageResource() {
return imageResource;
}
public String getFileName() {
return fileName;
}
}
XML 文件
activity_file_view.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.loopbreakr.firstpdf.FileView">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="4dp"
android:scrollbars="vertical"
android:background="@color/cardview_shadow_start_color"
/>
</RelativeLayout>
row.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_marginBottom="4dp"
app:cardCornerRadius="4dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="4dp">
<ImageView
android:id="@+id/fileImage"
android:layout_width="50dp"
android:layout_height="50dp"
android:padding="2dp"/>
<TextView
android:id="@+id/fileName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginStart="55dp"
android:layout_marginTop="5dp"
android:text="File Name"
android:textColor="@color/black"
android:textSize="20sp" />
<ImageView
android:id="@+id/deleteFile"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_margin="5dp"
android:padding="2dp"
android:src="@drawable/ic_delete" />
</RelativeLayout>
</androidx.cardview.widget.CardView>
编辑
我尝试按照建议将数组更改为数组列表,但我想我一定是做错了,因为这会导致崩溃。
FileView.java
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.widget.Toast;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class FileView extends AppCompatActivity {
private RecyclerView fileRecyclerView;
private RowAdapter fileAdapter;
private RecyclerView.LayoutManager fileLayoutManager;
private ArrayList<RowItem> rowItem;
List<File> fileList;
String filePath = "";
String fileData = "";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_file_view);
filePath = "PDF_files";
File file = new File(getExternalFilesDir(filePath).toString());
fileList = Arrays.asList(file.listFiles());
createRows();
buildRecyclerView();
}
public void createRows(){
rowItem = new ArrayList<>();
for (int i = 0; i < fileList.size(); i++) {
rowItem.add(new RowItem(R.drawable.ic_book,(fileList.get(i).getName().replace("__", " ").replace('_','\n').replace('-','/').replace(".pdf",""))));
}
}
public void removeItem(int position) {
rowItem.remove(position);
fileAdapter.notifyItemRemoved(position);
}
@Override
public void recreate() {
super.recreate();
}
public void buildRecyclerView() {
fileRecyclerView = findViewById(R.id.recyclerView);
fileRecyclerView.setHasFixedSize(true);
fileLayoutManager = new LinearLayoutManager(this);
fileAdapter = new RowAdapter(rowItem);
fileRecyclerView.setLayoutManager(fileLayoutManager);
fileRecyclerView.setAdapter(fileAdapter);
fileAdapter.setOnItemClickListener(new RowAdapter.OnItemClickListener() {
@Override
public void onItemClick(int position) {
fileData = fileList.get(position).toString();
Toast.makeText(FileView.this,"Clicked: " + fileData , Toast.LENGTH_SHORT).show();
}
@Override
public void onDeleteClick(int position) {
removeItem(position);
File deletePath = fileList.get(position);
deletePath.delete();
if(deletePath.exists()){
getApplicationContext().deleteFile(deletePath.getName());
}
fileList.remove(position);
}
});
}
}
当您删除记录时,table 小部件(您在设备上看到的东西)会更新并删除该行。但是,您的 fileList
数组没有更新;它仍然具有表示已删除文件的路径(当然,您删除了该文件,但是捕获该文件的 path 概念的任何对象仍然存在,当然)。
删除文件时,还需要修复fileList数组。考虑到数组不能增长或缩小,如果使用 List<File>
而不是 File[]
.
,这可能会简单得多
你保留两个列表让自己变得困难。
rowItems and fileList.
在 RowItems 中,您只有一个字符串变量文件名。
添加一个变量 String filePath 并使用它代替文件列表数组。
我正在尝试制作一个程序,在其中列出 recyclerview 中的文件名。使用行内的按钮,应用程序应通过存储在包含文件路径的数组中的路径删除项目。如果在 toast 消息中单击卡片本身,应用程序还应显示文件路径。
到目前为止,我可以执行此操作,但是当应用程序处于活动状态时,我一次只能删除一个文件。当我尝试删除多个文件时出现问题。这些项目从 recyclerview 中删除,一切看起来都很正常,但是如果应用程序关闭,那么我在第一个文件之后尝试删除的文件再次出现,表明它们没有被删除。
我的代码:
JAVA 类
FileView.java(这是主activity)
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.widget.Toast;
import java.io.File;
import java.util.ArrayList;
public class FileView extends AppCompatActivity {
private RecyclerView fileRecyclerView;
private RowAdapter fileAdapter;
private RecyclerView.LayoutManager fileLayoutManager;
private ArrayList<RowItem> rowItem;
File[] fileList;
String filePath = "";
String fileData = "";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_file_view);
filePath = "PDF_files";
File file = new File(getExternalFilesDir(filePath).toString());
fileList = file.listFiles();
createRows();
buildRecyclerView();
}
public void createRows(){
rowItem = new ArrayList<>();
for (int i = 0; i < fileList.length; i++) {
rowItem.add(new RowItem(R.drawable.ic_book,(fileList[i].getName().replace("__", " ").replace('_','\n').replace('-','/').replace(".pdf",""))));
}
}
public void removeItem(int position) {
rowItem.remove(position);
fileAdapter.notifyItemRemoved(position);
}
public void buildRecyclerView() {
fileRecyclerView = findViewById(R.id.recyclerView);
fileRecyclerView.setHasFixedSize(true);
fileLayoutManager = new LinearLayoutManager(this);
fileAdapter = new RowAdapter(rowItem);
fileRecyclerView.setLayoutManager(fileLayoutManager);
fileRecyclerView.setAdapter(fileAdapter);
fileAdapter.setOnItemClickListener(new RowAdapter.OnItemClickListener() {
@Override
public void onItemClick(int position) {
fileData = fileList[position].toString();
Toast.makeText(FileView.this,"Clicked: " + fileData , Toast.LENGTH_SHORT).show();
}
@Override
public void onDeleteClick(int position) {
removeItem(position);
File deletePath = fileList[position];
deletePath.delete();
if(deletePath.exists()){
getApplicationContext().deleteFile(deletePath.getName());
}
}
});
}
}
RowAdapter.java(这是适配器class)
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class RowAdapter extends RecyclerView.Adapter<RowAdapter.RowViewHolder> {
private ArrayList<RowItem> mRowList;
private OnItemClickListener mListener;
public interface OnItemClickListener{
void onItemClick(int position);
void onDeleteClick(int position);
}
public void setOnItemClickListener(OnItemClickListener listener){
mListener = listener;
}
public static class RowViewHolder extends RecyclerView.ViewHolder{
public ImageView rowImageView;
public TextView rowTextView;
public ImageView rowDeleteImage;
public RowViewHolder(@NonNull View itemView, OnItemClickListener listener) {
super(itemView);
rowImageView = itemView.findViewById(R.id.fileImage);
rowTextView = itemView.findViewById(R.id.fileName);
rowDeleteImage = itemView.findViewById(R.id.deleteFile);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(listener != null){
int position = getAdapterPosition();
if(position != RecyclerView.NO_POSITION){
listener.onItemClick(position);
}
}
}
});
rowDeleteImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(listener != null){
int position = getAdapterPosition();
if(position != RecyclerView.NO_POSITION){
listener.onDeleteClick(position);
}
}
}
});
}
}
public RowAdapter(ArrayList<RowItem> rowList){
mRowList = rowList;
}
@NonNull
@Override
public RowViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.row, parent, false);
RowViewHolder rvh = new RowViewHolder(v, mListener);
return rvh;
}
@Override
public void onBindViewHolder(@NonNull RowViewHolder holder, int position) {
RowItem currentItem = mRowList.get(position);
holder.rowImageView.setImageResource(currentItem.getImageResource());
holder.rowTextView.setText(currentItem.getFileName());
}
@Override
public int getItemCount() {
return mRowList.size();
}
}
RowItem.java(图像和文件名的获取器)
public class RowItem {
private int imageResource;
private String fileName;
public RowItem(int img, String stringInput) {
this.imageResource = img;
this.fileName = stringInput;
}
public int getImageResource() {
return imageResource;
}
public String getFileName() {
return fileName;
}
}
XML 文件
activity_file_view.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.loopbreakr.firstpdf.FileView">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="4dp"
android:scrollbars="vertical"
android:background="@color/cardview_shadow_start_color"
/>
</RelativeLayout>
row.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_marginBottom="4dp"
app:cardCornerRadius="4dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="4dp">
<ImageView
android:id="@+id/fileImage"
android:layout_width="50dp"
android:layout_height="50dp"
android:padding="2dp"/>
<TextView
android:id="@+id/fileName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginStart="55dp"
android:layout_marginTop="5dp"
android:text="File Name"
android:textColor="@color/black"
android:textSize="20sp" />
<ImageView
android:id="@+id/deleteFile"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_margin="5dp"
android:padding="2dp"
android:src="@drawable/ic_delete" />
</RelativeLayout>
</androidx.cardview.widget.CardView>
编辑 我尝试按照建议将数组更改为数组列表,但我想我一定是做错了,因为这会导致崩溃。
FileView.java
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.widget.Toast;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class FileView extends AppCompatActivity {
private RecyclerView fileRecyclerView;
private RowAdapter fileAdapter;
private RecyclerView.LayoutManager fileLayoutManager;
private ArrayList<RowItem> rowItem;
List<File> fileList;
String filePath = "";
String fileData = "";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_file_view);
filePath = "PDF_files";
File file = new File(getExternalFilesDir(filePath).toString());
fileList = Arrays.asList(file.listFiles());
createRows();
buildRecyclerView();
}
public void createRows(){
rowItem = new ArrayList<>();
for (int i = 0; i < fileList.size(); i++) {
rowItem.add(new RowItem(R.drawable.ic_book,(fileList.get(i).getName().replace("__", " ").replace('_','\n').replace('-','/').replace(".pdf",""))));
}
}
public void removeItem(int position) {
rowItem.remove(position);
fileAdapter.notifyItemRemoved(position);
}
@Override
public void recreate() {
super.recreate();
}
public void buildRecyclerView() {
fileRecyclerView = findViewById(R.id.recyclerView);
fileRecyclerView.setHasFixedSize(true);
fileLayoutManager = new LinearLayoutManager(this);
fileAdapter = new RowAdapter(rowItem);
fileRecyclerView.setLayoutManager(fileLayoutManager);
fileRecyclerView.setAdapter(fileAdapter);
fileAdapter.setOnItemClickListener(new RowAdapter.OnItemClickListener() {
@Override
public void onItemClick(int position) {
fileData = fileList.get(position).toString();
Toast.makeText(FileView.this,"Clicked: " + fileData , Toast.LENGTH_SHORT).show();
}
@Override
public void onDeleteClick(int position) {
removeItem(position);
File deletePath = fileList.get(position);
deletePath.delete();
if(deletePath.exists()){
getApplicationContext().deleteFile(deletePath.getName());
}
fileList.remove(position);
}
});
}
}
当您删除记录时,table 小部件(您在设备上看到的东西)会更新并删除该行。但是,您的 fileList
数组没有更新;它仍然具有表示已删除文件的路径(当然,您删除了该文件,但是捕获该文件的 path 概念的任何对象仍然存在,当然)。
删除文件时,还需要修复fileList数组。考虑到数组不能增长或缩小,如果使用 List<File>
而不是 File[]
.
你保留两个列表让自己变得困难。
rowItems and fileList.
在 RowItems 中,您只有一个字符串变量文件名。
添加一个变量 String filePath 并使用它代替文件列表数组。