Android - Listview .remove() 函数未按预期工作

标签 android listview

我有一个 ListView ,可以通过 onLongClick 删除特定图像,但目前无法正常工作。测试时,会出现对话框,如果我想删除或不想删除,我按是/确定, toast 出现说项目已删除,但该项目仍然存在。

已更新(感谢 user1140237,我可以使用删除和删除功能)

更新的主要 Activity

private String[] FilePathStrings;
private String[] FileNameStrings;
private File[] listFile;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_yearbook);
    File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"/CapturyGallery");

    // Check for SD Card
    if (!Environment.getExternalStorageState().equals(
            Environment.MEDIA_MOUNTED)) {
        Toast.makeText(this, "Error! No SDCARD Found!", Toast.LENGTH_LONG)
                .show();
    } else {
        // Locate the image folder in your SD Card
        file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"/CapturyGallery");
        // Create a new folder if no folder named CapturyGallery exist
        file.mkdirs();
    }


    if (file.isDirectory())
    {
        listFile = file.listFiles();
        // Create a String array for FilePathStrings
        FilePathStrings = new String[listFile.length];
        // Create a String array for FileNameStrings
        FileNameStrings = new String[listFile.length];

        for (int i = 0; i < listFile.length; i++)
        {
            //Get the path image file
            FilePathStrings[i] = listFile[i].getAbsolutePath();
            // Get the name image file
            FileNameStrings[i] = listFile[i].getName();
        }
    }
    Arrays.sort(listFile);

     final ListAdapter listAdapter = new CustomAdapter(Yearbook.this, FilePathStrings, FileNameStrings);
     ListView lv = (ListView) findViewById(R.id.ListingView);
     lv.setAdapter(listAdapter);

     final ArrayList<String> list = new ArrayList(Arrays.asList(FilePathStrings));





    lv.setOnItemClickListener(this);
    lv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
        @Override
        public boolean onItemLongClick(AdapterView<?> parent, View view, final int position, long id) {
            //Deletes item
            AlertDialog.Builder adb=new AlertDialog.Builder(Yearbook.this);
            adb.setTitle("Delete?");
            adb.setMessage("Are you sure you want to delete " + FileNameStrings[position]);
            final int positionToRemove = position;
            adb.setNegativeButton("Cancel", null);
            adb.setPositiveButton("Ok", new AlertDialog.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    File file = new File(list.get(positionToRemove));
                    if (file.delete()) {
                        list.remove(position);
                        ((CustomAdapter) listAdapter).updateMyData(FilePathStrings, FileNameStrings);
                        Toast.makeText(getApplicationContext(), FileNameStrings[position] + " deleted", Toast.LENGTH_LONG).show();
                    }


                }
            });
            adb.show();
            return true;
        }

    });


}

自定义适配器

public class CustomAdapter extends BaseAdapter {

private Activity activity;
private String[] filepath;
private String[] filename;


private static LayoutInflater inflater = null;

public CustomAdapter(Activity a, String[] fpath, String[] fname) {
    activity = a;
    filepath = fpath;
    filename = fname;
    inflater = (LayoutInflater) activity
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);


}
public void updateMyData(String[] fpath, String[] fname) {
    filepath = fpath;
    filename = fname;
    notifyDataSetChanged();
}


@Override
public int getCount() {
    return filepath.length;

}

public Object getItem(int position) {
    return position;
}

public long getItemId(int position) {
    return position;
}

class MyViewHolder {
    ImageView myImage;
    TextView timestamp;
    TextView myName;
    TextView myHeader;
    MyViewHolder(View v) {
        myImage = (ImageView) v.findViewById(R.id.PicView);
        timestamp = (TextView) v.findViewById(R.id.timestamp);
        myName = (TextView) v.findViewById(R.id.myName);
        myHeader = (TextView) v.findViewById(R.id.textSeparator);

    }
}


@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View vi = convertView;
    MyViewHolder holder = null;
    if (vi == null) {
        vi = inflater.inflate(R.layout.custom_row, null);
        holder = new MyViewHolder(vi);
        vi.setTag(holder);
    } else {
        holder = (MyViewHolder) vi.getTag();
    }

    Bitmap bmp = ThumbnailUtils.extractThumbnail(BitmapFactory.decodeFile(filepath[position]),100,100);


    holder.myImage.setImageBitmap(bmp);
    //PicImage.setScaleType(ImageView.ScaleType.CENTER_CROP);
    holder.myImage.setPadding(8, 8, 8, 8);

    //Set Title
    holder.myName.setText(filename[position]);

    ExifInterface intf = null;
    try {
        intf = new ExifInterface(filepath[position]);
    } catch(IOException e) {
        e.printStackTrace();
    }

    if(intf != null) {
        String dateString = intf.getAttribute(ExifInterface.TAG_DATETIME);
        holder.timestamp.setText("Date Taken: " + dateString.toString());
    }


    return vi;
}

所以我的最后一个问题是,每当我从 ListView 中删除某些内容时,它就会崩溃。但是,文件确实被删除了。我不确定是什么错误,因为我在手机上测试过

最佳答案

您还需要更新自定义适配器中的列表数据。删除后调用 notifydatasetchanged

在您的自定义适配器中保留以下方法以更新列表数据,然后在长按中调用它

public void updateMyData(String[] fpath, String[] fname) {
            filepath = fpath;
            filename = fname;
            notifyDataSetChanged();
        }

你需要从 longPress 调用它

 list.remove(position);
                    ((CustomAdapter )listAdapter).updateMyData( FilePathStrings, FileNameStrings); /// here in your case you need to define both array global sorry not time to clean up your code
                    Toast.makeText(getApplicationContext(), FileNameStrings[position] +" deleted",Toast.LENGTH_LONG).show();

已更新

要从提到的目录中删除文件并更新 ListView ,您需要先从该位置删除文件,然后再更新 ListView

 File file = new File(list.get(position));
            if (file.delete()) {// this will required permission in Manifest for Write_EXTERNAL_STORATE
                // if file is deleted from SD CARD
                list.remove(position);
                ((CustomAdapter )listAdapter).updateMyData( FilePathStrings, FileNameStrings); /// here in your case you need to define both array global sorry not time to clean up your code
                Toast.makeText(getApplicationContext(), FileNameStrings[position] + " deleted", Toast.LENGTH_LONG).show();
            }

*自定义适配器 *

public class CustomAdapter extends BaseAdapter {

        private Activity activity;
        private ArrayList<String> filepath;
        private ArrayList<String> filename;
        private JSONArray jListData;
        private int size = 0;

        public CustomAdapter(Activity a, JSONArray jListData) {
            activity = a;
            this.jListData = jListData;
            if (filepath != null)
                size = jListData.length();


        }

        public void updateMyData(JSONArray jListData) {
            this.jListData = jListData;
            size = jListData.length();
            notifyDataSetChanged();
        }


        @Override
        public int getCount() {
            return size;

        }

        public JSONObject getItem(int position) {
            try {
                return (JSONObject) jListData.get(position);
            } catch (JSONException e) {
                e.printStackTrace();
            }
            return null;
        }

        public long getItemId(int position) {
            return position;
        }

        class MyViewHolder {
            ImageView myImage;
            TextView timestamp;
            TextView myName;
            TextView myHeader;

            MyViewHolder(View v) {
                myImage = (ImageView) v.findViewById(R.id.PicView);
                timestamp = (TextView) v.findViewById(R.id.timestamp);
                myName = (TextView) v.findViewById(R.id.myName);
                myHeader = (TextView) v.findViewById(R.id.textSeparator);

            }
        }


        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View vi = convertView;
            MyViewHolder holder = null;
            try {
                if (vi == null) {
                    vi = LayoutInflater.from(activity).inflate(R.layout.custom_row, parent, false);
                    holder = new MyViewHolder(vi);
                    vi.setTag(holder);
                } else {
                    holder = (MyViewHolder) vi.getTag();
                }
                JSONObject rowObject = this.jListData.getJSONObject(position);
                Bitmap bmp = ThumbnailUtils.extractThumbnail(BitmapFactory.decodeFile(rowObject.optString("filename")), 100, 100);


                holder.myImage.setImageBitmap(bmp);
                //PicImage.setScaleType(ImageView.ScaleType.CENTER_CROP);
                holder.myImage.setPadding(8, 8, 8, 8);

                //Set Title
                holder.myName.setText(rowObject.optString("filename"));

                ExifInterface intf = null;
                try {
                    intf = new ExifInterface(rowObject.optString("filepath"));
                } catch (IOException e) {
                    e.printStackTrace();
                }

                if (intf != null) {
                    String dateString = intf.getAttribute(ExifInterface.TAG_DATETIME);
                    holder.timestamp.setText("Date Taken: " + dateString.toString());
                }
            } catch (JSONException e) {
            }


            return vi;
        }
    }

Activity

private JSONArray jArrayFileData;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_yearbook);
        File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "/CapturyGallery");

        // Check for SD Card
        if (!Environment.getExternalStorageState().equals(
                Environment.MEDIA_MOUNTED)) {
            Toast.makeText(this, "Error! No SDCARD Found!", Toast.LENGTH_LONG)
                    .show();
        } else {
            // Locate the image folder in your SD Card
            file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "/CapturyGallery");
            // Create a new folder if no folder named CapturyGallery exist
            file.mkdirs();
        }

        jArrayFileData = new JSONArray();
        if (file.isDirectory()) {
            listFile = file.listFiles();
            // Create a String array for FilePathStrings
            FilePathStrings = new String[listFile.length];
            // Create a String array for FileNameStrings
            FileNameStrings = new String[listFile.length];

            for (int i = 0; i < listFile.length; i++) {
                JSONObject jObject = new JSONObject();
                //Get the path image file
//                FilePathStrings[i] = listFile[i].getAbsolutePath();
                // Get the name image file
//                FileNameStrings[i] = listFile[i].getName();
                jObject.put("filepath", listFile[i].getAbsolutePath());
                jObject.put("filename", listFile[i].getName());
                jArrayFileData.put(jObject);
            }
        }
//        Arrays.sort(listFile);

        final ListAdapter listAdapter = new CustomAdapter(Yearbook.this, jArrayFileData);
        ListView lv = (ListView) findViewById(R.id.ListingView);
        lv.setAdapter(listAdapter);

//        final ArrayList<String> list = new ArrayList(Arrays.asList(FilePathStrings));


        lv.setOnItemClickListener(this);
        lv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view, final int position, long id) {
                //Deletes item
                AlertDialog.Builder adb = new AlertDialog.Builder(Yearbook.this);
                adb.setTitle("Delete?");
                adb.setMessage("Are you sure you want to delete " + FileNameStrings[position]);
                final int positionToRemove = position;
                adb.setNegativeButton("Cancel", null);
                adb.setPositiveButton("Ok", new AlertDialog.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        try {
                            File file = new File(list.get(positionToRemove));
                            if (file.delete()) {
                                Toast.makeText(getApplicationContext(), jArrayFileData.getJSONObject(position).optString("filename") + " deleted", Toast.LENGTH_LONG).show();
                                jArrayFileData.remove(position);
    //                            list.remove(position);
                                ((CustomAdapter) listAdapter).updateMyData(jArrayFileData);

                            }
                        } catch (JSONException e) {
                        }


                    }
                });
                adb.show();
                return true;
            }

        });


    }

关于Android - Listview .remove() 函数未按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34691126/

相关文章:

Android Studio - 相对布局中软键盘上方的小部件

java - onTouchListener 一个ImageView需要点击两次才能起作用,另一个只需点击一次

android - 带有可见分隔线的不可点击 ListView 项目

android - 使用 appcompat v21 将 TextView 设置为 Spinner

android - 使用表示资源名称的变量访问 R.string 的内容

listview - 如何在Xamarin.Forms中调整水平ListView的大小?

listview - 如何在 ListView 的 TextCell 中包装文本?

Android:如何刷新 ListView 内容?

java - 将 ActivityResult 数据发送到另一个 Activity 的有效方法

android - 在 ListView 中显示来自远程服务器的数据