【问题标题】:ContextMenu Fails To Remove Row From ListView With Custom AdapterContextMenu 无法使用自定义适配器从 ListView 中删除行
【发布时间】:2017-11-13 20:57:49
【问题描述】:

问题是:我的 ContextMenu 无法使用自定义适配器从 ListView 中删除一行,并且 应用程序因错误而崩溃:UnsupportedOperationException,请参阅 Logcat 输出。

我已经完成了 Google 搜索并搜索了 stackoverflow。我找到的信息都没有解决这个问题。

我的问题是:我的代码有什么问题? 请提供正确的代码来解决这个问题。

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

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)

【问题讨论】:

    标签: java android listview android-adapter android-contextmenu


    【解决方案1】:

    我修改了你的工作:

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

    【讨论】:

      【解决方案2】:

      只需在该特定位置从 nameArraymodifiedArray 中删除项目,然后通知 adapter 数据集更改。

      我明白了。一个大错误是在需要动态大小数组的地方使用固定大小的数组。

      改变你的

      String nameArray[];
      String modifiedArray[];
      

      ArrayList<String> nameArray;
       ArrayList<String> modifiedArray;
      

      【讨论】:

      • 1.您是说要删除 nameArray 和 modifiedArray 的所有代码吗? 2. 如果我这样做,我的 ListView 将没有任何数据显示在 TextViews 中。
      • 删除在该位置找到的特定项目。由于您有 2 个数组列表:nameArray 和 modifiedArray,因此您必须在每个数组上删除该位置的项目。
      • 也改变这些:private String itemNameArray[];私有字符串 dateArray[];
      • 1.我的 ListView 包括 CustomListViewAdapter 类及其 String 数组,它一直很好地显示 ListView 和所有填充数据的行。 2. 我现在的目标是删除通过长按行选择的整个行。 3. 我不想只从行中的 TextViews 中删除数据。 4. 看起来您下面的代码正在尝试仅从行中的 TextViews 中删除数据: itemNameArray.remove(listView.getSelectedItemPosition()); dateArray.remove(listView.getSelectedItemPosition());
      • 我觉得,你不懂!!!!!!!!!!!! [] 数组如 String[] 用于固定大小数组 !!!;;!!!!!!!!!!!!!!!!!!!!!!!!你不能缩小或扩大它的大小!!!!!!!!!!要增加或减少数组中的项数,必须使用数组的 Collections 包,例如 ArrayList。 !!!!!!!!!!!!!!!!!!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-16
      • 1970-01-01
      • 2022-11-01
      • 1970-01-01
      相关资源
      最近更新 更多