删除多个图像的Java Index out of bounds exception

时间:2016-07-08 10:18:00

标签: java android image

我正在创建一个Android应用程序,其中用户可以捕获图像,这些图像显示在gridview中。当用户想要通过触摸图像删除一个或多个图像我得到一个java索引越界异常。我见过的例子使用了扩展到arrayadapter的图像适配器,但我使用的是扩展到基本适配器的图像适配器。所以我不知道因为它发生了错误。

grid.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
        @Override
        public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
            final int checkedCount = grid.getCheckedItemCount();
            mode.setTitle(checkedCount + " Selected");
            adapter.toggleSelection(position);
        }

        @Override
        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            mode.getMenuInflater().inflate(R.menu.delete_mode, menu);
            return true;
        }

        @Override
        public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
            return false;
        }

        @Override
        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
            switch (item.getItemId()) {
                case R.id.delete:
                    // Calls getSelectedIds method from ListViewAdapter Class
                    SparseBooleanArray selected = adapter
                            .getSelectedIds();
                    // Captures all selected ids with a loop

                    for (int i = (selected.size() - 1); i >= 0; i--) {
                         if (selected.valueAt(i)) {
                              int selecteditem = (int) adapter
                                    .getItem(selected.keyAt(i));
                             //Remove selected items following the ids


                                 String imgPath = listOfImagesPath.get(selecteditem);
                                 File file=new File(imgPath);
                                 file.delete();
                             adapter.removeitem(selecteditem);

                        }
                    }
                    // Close CAB
                    mode.finish();
                    return true;
                default:
                    return false;
            }
        }

        @Override
        public void onDestroyActionMode(ActionMode actionMode) {
            adapter.removeSelection();
        }
    });

图像适配器(我已创建):

public class ImageListAdapter extends BaseAdapter
{
    private Context context;
    private List<String> imgPic;
    private SparseBooleanArray mSelectedItemsIds;
    public ImageListAdapter(Context c, List<String> thePic)
    {
        context = c;
        imgPic = thePic;
        mSelectedItemsIds = new SparseBooleanArray();
    }
    public int getCount() {
        if(imgPic != null)
            return imgPic.size();
        else
            return 0;
    }

    //---returns the ID of an item---
    public Object getItem(int position) {
        return position;
    }

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

    public void removeitem(int position){
        imgPic.remove(position);
        notifyDataSetChanged();

    }
    public void toggleSelection(int position) {
        selectView(position, !mSelectedItemsIds.get(position));
    }

    public void removeSelection() {
        mSelectedItemsIds = new SparseBooleanArray();
        notifyDataSetChanged();
    }

    public void selectView(int position, boolean value) {
        if (value)
            mSelectedItemsIds.put(position, value);
        else
            mSelectedItemsIds.delete(position);
        notifyDataSetChanged();
    }

    public int getSelectedCount() {
        return mSelectedItemsIds.size();
    }

    public SparseBooleanArray getSelectedIds() {
        return mSelectedItemsIds;
    }

    //---returns an ImageView view---
    public View getView(int position, View convertView, ViewGroup parent)
    {
        ImageView imageView;
        BitmapFactory.Options bfOptions=new BitmapFactory.Options();
        bfOptions.inDither=false;                     //Disable Dithering mode
        bfOptions.inPurgeable=true;                   //Tell to gc that whether it needs free memory, the Bitmap can be cleared
        bfOptions.inInputShareable=true;              //Which kind of reference will be used to recover the Bitmap data after being clear, when it will be used in the future
        bfOptions.inTempStorage=new byte[32 * 1024];
        if (convertView == null) {
            imageView = new ImageView(context);
            imageView.setLayoutParams(new GridView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
            imageView.setPadding(0, 0, 0, 0);
        } else {
            imageView = (ImageView) convertView;
        }
        FileInputStream fs = null;
        Bitmap bm;
        try {
            fs = new FileInputStream(new File(imgPic.get(position).toString()));

            if(fs!=null) {
                bm=BitmapFactory.decodeFileDescriptor(fs.getFD(), null, bfOptions);
                imageView.setImageBitmap(bm);
                imageView.setId(position);
                imageView.setLayoutParams(new GridView.LayoutParams(200, 160));
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally{
            if(fs!=null) {
                try {
                    fs.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return imageView;
    }
}

图像适配器(我看到删除网格中多个图像的示例)

public class ListViewAdapter extends ArrayAdapter<WorldPopulation> {
// Declare Variables
Context context;
LayoutInflater inflater;
List<WorldPopulation> worldpopulationlist;
private SparseBooleanArray mSelectedItemsIds;

public ListViewAdapter(Context context, int resourceId,
        List<WorldPopulation> worldpopulationlist) {
    super(context, resourceId, worldpopulationlist);
    mSelectedItemsIds = new SparseBooleanArray();
    this.context = context;
    this.worldpopulationlist = worldpopulationlist;
    inflater = LayoutInflater.from(context);
}

private class ViewHolder {
    TextView rank;
    TextView country;
    TextView population;
    ImageView flag;
}

public View getView(int position, View view, ViewGroup parent) {
    final ViewHolder holder;
    if (view == null) {
        holder = new ViewHolder();
        view = inflater.inflate(R.layout.listview_item, null);
        // Locate the TextViews in listview_item.xml
        holder.rank = (TextView) view.findViewById(R.id.rank);
        holder.country = (TextView) view.findViewById(R.id.country);
        holder.population = (TextView) view.findViewById(R.id.population);
        // Locate the ImageView in listview_item.xml
        holder.flag = (ImageView) view.findViewById(R.id.flag);
        view.setTag(holder);
    } else {
        holder = (ViewHolder) view.getTag();
    }
    // Capture position and set to the TextViews
    holder.rank.setText(worldpopulationlist.get(position).getRank());
    holder.country.setText(worldpopulationlist.get(position).getCountry());
    holder.population.setText(worldpopulationlist.get(position)
            .getPopulation());
    // Capture position and set to the ImageView
    holder.flag.setImageResource(worldpopulationlist.get(position)
            .getFlag());
    return view;
}

@Override
public void remove(WorldPopulation object) {
    worldpopulationlist.remove(object);
    notifyDataSetChanged();
}

public List<WorldPopulation> getWorldPopulation() {
    return worldpopulationlist;
}

public void toggleSelection(int position) {
    selectView(position, !mSelectedItemsIds.get(position));
}

public void removeSelection() {
    mSelectedItemsIds = new SparseBooleanArray();
    notifyDataSetChanged();
}

public void selectView(int position, boolean value) {
    if (value)
        mSelectedItemsIds.put(position, value);
    else
        mSelectedItemsIds.delete(position);
    notifyDataSetChanged();
}

public int getSelectedCount() {
    return mSelectedItemsIds.size();
}

public SparseBooleanArray getSelectedIds() {
    return mSelectedItemsIds;
}

错误:

java.lang.IndexOutOfBoundsException: Invalid index 1, size is 0
        at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
        at java.util.ArrayList.remove(ArrayList.java:403)
        at nidhinkumar.gridcam.Cam$ImageListAdapter.removeitem(Cam.java:360)
        at nidhinkumar.gridcam.Cam$4.onActionItemClicked(Cam.java:200)
        at android.widget.AbsListView$MultiChoiceModeWrapper.onActionItemClicked(AbsListView.java:6693)
        at com.android.internal.policy.impl.PhoneWindow$DecorView$ActionModeCallbackWrapper.onActionItemClicked(PhoneWindow.java:3430)
        at android.support.v7.view.SupportActionModeWrapper$CallbackWrapper.onActionItemClicked(SupportActionModeWrapper.java:168)
        at android.support.v7.app.AppCompatDelegateImplV7$ActionModeCallbackWrapperV7.onActionItemClicked(AppCompatDelegateImplV7.java:1703)
        at android.support.v7.app.AppCompatDelegateImplV7$ActionModeCallbackWrapperV7.onActionItemClicked(AppCompatDelegateImplV7.java:1703)
        at android.support.v7.view.StandaloneActionMode.onMenuItemSelected(StandaloneActionMode.java:136)

我只有在捕获后尝试删除图像时才会出现此错误。当我重新加载页面并删除图像时,它可以正常工作。

1 个答案:

答案 0 :(得分:0)

这里可能有问题:

    @Override
    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
        switch (item.getItemId()) {
            case R.id.delete:
                // Calls getSelectedIds method from ListViewAdapter Class
                SparseBooleanArray selected = adapter
                        .getSelectedIds();
                // Captures all selected ids with a loop

                for (int i = (selected.size() - 1); i >= 0; i--) {

在这一行

SparseBooleanArray selected = adapter
                        .getSelectedIds();

选中不是数组。所以它的大小永远是一个。并且你从它中减去1,从而使它的大小为0.因此,只要你试图访问它,它总是会给出数组索引超出绑定的异常。

一个简单的结果可能就是这样:

SparseBooleanArray[] selected = adapter
                        .getSelectedIds();