我正在创建一个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)
我只有在捕获后尝试删除图像时才会出现此错误。当我重新加载页面并删除图像时,它可以正常工作。
答案 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();