在 Android 中按下提交按钮时使用自定义适配器从列表视图中获取选定的项目

Get selected items from listview using custom adapter on submit button pressed in Android

我已经创建了自己的适配器 InteractiveArrayAdapter,并将其设置为 xml 布局文件中的列表视图 (MyListView) 的适配器,比方说 MyActivity。然后,从 MyActivity activity,我执行这个:

MyActivity.java:

        ListView listView = (ListView) findViewById(R.id.MyListView);

        ArrayAdapter<Model> adapter = new InteractiveArrayAdapter(this, model);
        listView.setAdapter(adapter);

我的自定义适配器使用我创建的自定义模型 Model 来处理列表视图中的每个元素。每个列表视图项目,由一个 TextView 和一个 CheckBox 组成。

我的目标是在用户按下放置在 MyActivity xml 布局文件中的提交按钮时获取已检查项目的完整列表,因此我执行以下步骤来消除此问题:

  1. 在我的自定义适配器 InteractiveArrayAdapter 中,我声明了一个私有集来存储在列表视图中选择的每个元素的标识符。我使用自己的标识符而不是使用列表中的位置。这个标识符来自数据库中的主键,在上一步中我从中提取了所有需要的项目来填充列表视图。由于项目的标识符不能重复,所以我使用 Set。每次选中或取消选中列表视图中的项目时,都会更新此集合。我还对 return 这个集合实施了 public 方法。

    public class InteractiveArrayAdapter extends ArrayAdapter<Model> {
    
    ...
    
    private Set<Integer> checked = new HashSet<Integer>();
    
    ...
    
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view = null;
    
        viewHolder.checkbox = (CheckBox) view.findViewById(R.id.interactiveRowCheck);
        viewHolder.checkbox
                .setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
    
                    @Override
                    public void onCheckedChanged(CompoundButton buttonView,
                                                 boolean isChecked) {
                        Model element = (Model) viewHolder.checkbox
                                .getTag();
                        element.setSelected(buttonView.isChecked());
    
                        Integer id = element.getId();
                        if (isChecked) {
                            checked.add(id);
                        } else if (checked.contains(id)) {
                            checked.remove(id);
                        }
                    }
                });
    }
    
    public Set<Integer> getCheckedItems() {
        return this.checked;
    }
    }
    
  2. in MyActivity.java 我处理点击按钮并尝试阅读 通过这样做检查的项目列表:

    public void OnClickCompareButton(View view) {
        InteractiveArrayAdapter adapter;
    
        Set<Integer> checkedItems = adapter.getCheckedItems();
        Iterator<Integer> it = checkedItems.iterator();
    
        int size = checkedItems.size();
        for (int i = 0; i < size; i++) {
            // Do whatever...
        }
    }
    

但是 Android Studio 在编译时抛出错误:

Error:(82, 37) error: variable adapter might not have been initialized

如果那么我在设置adapter的时候使用了这个post开头初始化的变量adapter,即:

    public void OnClickCompareButton(View view) {
        Set<Integer> checkedItems = this.adapter.getCheckedItems();
        Iterator<Integer> it = checkedItems.iterator();

        int size = checkedItems.size();
        for (int i = 0; i < size; i++) {
            // Do whatever...
        }
    }

编译时出现以下错误:

Error:(82, 49) error: cannot find symbol method getCheckedItems()

那么如何解决呢?

Error:(82, 37) error: variable adapter might not have been initialized

确实如此 - adapter 已在上面声明但未初始化,所以如果编译器没有先到达那里,无论如何都会 null

乍一看,您的第二种方法似乎更有可能奏效,因此:

Error:(82, 49) error: cannot find symbol method getCheckedItems()

这是因为 Adapter 的声明类型是 ListAdapter(参见 getAdapter(),可以说是访问字段的首选方式),而不是您的子类 InteractiveArrayAdapter.

你可以施法:

Set<Integer> checkedItems = ((InteractiveArrayAdapter) getListAdapter()).getCheckedItems();

并且为了避免与 ArrayAdapter 混淆,您可以简化实例化/传递给您的视图:

ListView listView = (ListView) findViewById(R.id.MyListView);
listView.setAdapter(new InteractiveArrayAdapter(this, model));

此外,一些次要的代码风格要点:

  • 根据 official Java standards.
  • ,最好让所有方法名称都以小写字母开头
  • 您通常可以在方法中删除 this.(例如 return this.checked; -> return checked;