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

时间:2016-01-09 07:59:34

标签: android listview

我有一个能够通过onLongClick删除特定图像的列表视图,但到目前为止它还没有工作。测试时,会出现对话框如果我想要删除,我按是/确定并且吐司显示项目已删除,但该项目仍在那里。

更新(由于user1140237,我的删除和删除功能正常工作)

更新主要活动

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;
        }

    });


}

CUSTOMADAPTER

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;
}

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

2 个答案:

答案 0 :(得分:1)

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

在您的惯例中保留以下方法来更新列表数据&amp;之后在longpress中调用它

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();

<强>已更新

从提到的目录中删除文件&amp;更新列表视图您需要先从该位置删除文件,而不是需要更新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();
            }

* CustomAdapter *

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;
        }
    }

<强> 活性

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;
            }

        });


    }

答案 1 :(得分:0)

在代码中使用Arraylist<String>表示fpath和fname:然后从列表视图中删除数据。 使用此:

fpath.remove(index_toDelete);
fpath.remove(index_toDelete);
customAdapter.notifyDataSetChanged();