The Problem is: My ContextMenu Fails to Remove a Row from ListView with a Custom Adapter and the app crashes with the error: UnsupportedOperationException, see Logcat output.
I have done Google searches and searched stackoverflow. None of the information I have found solves this problem.
My Question is: What is wrong with my code? Please provide the correct code to solve this problem.
Java Code:
public class TestActivity extends ListActivity {
private String itemNameArray[];
private String dateArray[];
private ListView listview;
CustomListViewAdapter customListViewAdapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
registerForContextMenu(getListView());
root = Environment.getExternalStorageDirectory() + File.separator + "/ListTestFiles";
getDir(root);
listview = getListView();
name=itemNameArray;
lastmod=dateArray;
customListViewAdapter = new CustomListViewAdapter(this, name, lastmod);
listview.setAdapter(customListViewAdapter);
} // End of onCreate code.
class CustomListViewAdapter extends ArrayAdapter<String> {
Context context;
String[] nameArray;
String[] modifiedArray;
CustomListViewAdapter(Context c, String[] name, String[] lastmod)
{
super(c, R.layout.layout_item_view, R.id.rowtext, name);
this.context = c;
this.nameArray = name;
this.modifiedArray = lastmod;
}
public View getView(int position, View convertView, ViewGroup parent)
{
LayoutInflater inflater=(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View row = inflater.inflate(R.layout.layout_item_view, parent, false);
TextView myName;
TextView myLastMod;
myName=(TextView) row.findViewById(R.id.rowtext);
myName.setText(nameArray[position]);
myLastMod=(TextView) row.findViewById(R.id.textView6);
myLastMod.setText(modifiedArray[position]);
return row;
}
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.context_menu, menu);
}
@Override
public boolean onContextItemSelected(MenuItem itemMenu) {
final AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)itemMenu.getMenuInfo();
switch (itemMenu.getItemId()) {
case R.id.context_menu_rename:
Toast.makeText(this, "Rename", Toast.LENGTH_SHORT).show();
return true;
case R.id.context_menu_delete:
// NOTE TESTING the line of code below caused a runtime error: java.lang.UnsupportedOperationException
customListViewAdapter.remove(customListViewAdapter.getItem(info.position));
customListViewAdapter.notifyDataSetChanged();
Toast.makeText(getApplicationContext(), "position = " + info.position, Toast.LENGTH_SHORT).show();
Toast.makeText(this, "Delete", Toast.LENGTH_SHORT).show();
return true;
return super.onContextItemSelected(itemMenu);
}
}
}
Logcat output:
11-13 10:45:21.229 21432-21432/com.testing.listapp D/AndroidRuntime﹕ Shutting down VM
--------- beginning of crash
11-13 10:45:21.246 21432-21432/com.testing.listapp E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.testing.listapp, PID: 21432
java.lang.UnsupportedOperationException
at java.util.AbstractList.remove(AbstractList.java:638)
at java.util.AbstractList$SimpleListIterator.remove(AbstractList.java:75)
at java.util.AbstractCollection.remove(AbstractCollection.java:229)
at android.widget.ArrayAdapter.remove(ArrayAdapter.java:244)
at com.testing.listapp.TestActivity.onContextItemSelected(TestActivity.java:5468)
at android.app.Activity.onMenuItemSelected(Activity.java:2905)
at com.android.internal.policy.impl.PhoneWindow$DialogMenuCallback.onMenuItemSelected(PhoneWindow.java:4701)
at com.android.internal.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:761)
at com.android.internal.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:152)
at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:904)
at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:894)
at com.android.internal.view.menu.MenuDialogHelper.onClick(MenuDialogHelper.java:167)
at com.android.internal.app.AlertController$AlertParams$3.onItemClick(AlertController.java:1082)
at android.widget.AdapterView.performItemClick(AdapterView.java:305)
at android.widget.AbsListView.performItemClick(AbsListView.java:1146)
at android.widget.AbsListView$PerformClick.run(AbsListView.java:3053)
at android.widget.AbsListView$3.run(AbsListView.java:3860)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
I modified your work:
public class TestActivity extends ListActivity {
private ArrayList<String> itemNameArray;
private ArrayList<String> dateArray;
private ListView listview;
CustomListViewAdapter customListViewAdapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
registerForContextMenu(getListView());
String root = Environment.getExternalStorageDirectory() + File.separator + "/ListTestFiles";
getDir(root);
listview = getListView();
CustomListViewAdapter = new CustomListViewAdapter(this, itemNameArray, dateArray);
listview.setAdapter(customListViewAdapter);
}
// End of onCreate code. class
CustomListViewAdapter extends ArrayAdapter<String> {
ArrayList<String> nameArray;
ArrayList<String> modifiedArray; CustomListViewAdapter(Context c, ArrayList<String> name, ArrayList<String> lastmod) {
super(c, 0, name);
this.nameArray = name;
this.modifiedArray = lastmod;
}
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater=LayoutInflater.from(parent.get context());
convertView = inflater.inflate(R.layout.layout_item_view, parent, false);
TextView myName;
TextView myLastMod;
myName=(TextView) row.findViewById(R.id.rowtext);
myName.setText(nameArray.get(position));
myLastMod=(TextView) row.findViewById(R.id.textView6);
myLastMod.setText(modifiedArray.get(position));
return convertView;
}
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
getMenuInflater().inflate(R.menu.context_menu, menu);
}
@Override
public boolean onContextItemSelected(MenuItem itemMenu) {
switch (itemMenu.getItemId()) {
case R.id.context_menu_rename:
Toast.makeText(this, "Rename", Toast.LENGTH_SHORT).show();
break;
case R.id.context_menu_delete: itemNameArray.remove(listView.getSelectedItemPosition());
dateArray.remove(listView.getSelectedItemPosition()); customListViewAdapter.notifyDataSetChanged();
break;
}
return true;
}
}