El problema es: mi ContextMenu no puede eliminar una fila de ListView con un adaptador personalizado y la aplicación se bloquea con el error: UnsupportedOperationException, consulte la salida de Logcat.

He hecho búsquedas en Google y he buscado en stackoverflow. Ninguna de la información que he encontrado resuelve este problema.

Mi pregunta es: ¿qué problema tiene mi código? Proporcione el código correcto para resolver este problema.

Código Java:

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

Salida de Logcat:

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)
-2
user2308699 13 nov. 2017 a las 23:57

2 respuestas

La mejor respuesta

Modifiqué tu trabajo:

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;
     }
     }
0
Francis Nduba Numbi 14 nov. 2017 a las 09:49

Simplemente elimine elementos de nameArray y modifiedArray en esa posición en particular, luego notifique al adaptador de los cambios en el conjunto de datos.

Veo. Un gran error es usar una matriz de tamaño fijo en un lugar que requiere una matriz de tamaño dinámico.

Cambie su

String nameArray[];
String modifiedArray[];

Para

ArrayList<String> nameArray;
 ArrayList<String> modifiedArray;
0
Francis Nduba Numbi 14 nov. 2017 a las 09:09