【问题标题】:Why is only one file getting deleted when I click to delete multiple?为什么单击删除多个文件时只有一个文件被删除?
【发布时间】:2021-01-27 07:57:44
【问题描述】:

我正在尝试制作一个程序,在其中列出 recyclerview 中的文件名。使用行内的按钮,应用程序应通过存储在包含文件路径的数组中的路径删除项目。如果在 toast 消息中单击卡片本身,应用程序还应显示文件路径。

到目前为止,我能够做到这一点,但是当应用程序处于活动状态时,我一次只能删除一个文件。当我尝试删除多个文件时出现问题。这些项目从 recyclerview 中删除,一切看起来都很正常,但如果应用程序关闭,那么我在第一个之后尝试删除的文件再次出现,表明它们没有被删除。

我的代码:

JAVA 类

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;
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(这是适配器类)

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>

行.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);
            }
        });
    }
}

【问题讨论】:

  • trying to make a program where I list the file names in a recyclerview. 什么名字?请编辑您的帖子。字体使用评论。
  • 请查看 oncreate 和 createrows 方法,我正在访问路径并能够以这种方式显示和打开它们 :) 我可以在创建应用程序时使用路径,但不是多个

标签: java android file android-recyclerview android-file


【解决方案1】:

当您删除一条记录时,表格小部件(您在设备上看到的内容)会更新并删除该行。但是,您的 fileList 数组未更新;它仍然具有代表该已删除文件的路径(当然,您删除了该文件,但是任何捕获该文件的 path 概念的对象仍然存在,当然)。

删除文件时,还需要修复 fileList 数组。鉴于数组不能增长或缩小,如果您使用 List&lt;File&gt; 而不是 File[],这可能会简单得多。

【讨论】:

  • 有趣,为什么我可以这样删除单个条目,但在创建应用程序时不能删除多个条目?
  • 因为一开始,fileList 变量和您的表格小部件仍然匹配。删除文件后,它们不再是您删除的第一个文件?这样可行。你删除的第二个文件?删除 another 文件,而不是您选择的文件(即,表格 UI 小部件的索引映射到不再匹配的 fileList,并且该文件被删除)。据推测,如果您目睹“仅删除一个文件”,您会一直尝试删除同一个文件。
  • 这很有道理,谢谢解释!然而,在尝试做可能不正确之后,当我点击删除时,我的应用程序崩溃了,我将编辑后的代码放在帖子中。
【解决方案2】:

因为你保留了两个列表,所以你自己很难做到。

rowItems and fileList. 

在 RowItems 中,您只有一个字符串变量 fileName。

添加一个变量 String filePath 并使用它来代替文件列表数组。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-25
    • 2014-08-12
    • 2013-08-18
    • 2021-05-17
    • 1970-01-01
    • 2018-02-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多