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

Posted

技术标签:

【中文标题】在Android中按下提交按钮时使用自定义适配器从列表视图中获取选定项目【英文标题】:Get selected items from listview using custom adapter on submit button pressed in Android 【发布时间】:2015-03-16 13:05:49 【问题描述】:

我创建了自己的适配器 InteractiveArrayAdapter,并将其设置为我在我的 xml 布局文件中的列表视图 (MyListView) 的适配器,比如说 MyActivity。然后,从 MyActivity 活动中,我执行以下操作:

MyActivity.java

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

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

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

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

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

    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;
    
    
    

    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,即:

    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()

那么如何解决呢?

【问题讨论】:

【参考方案1】:

错误:(82, 37) 错误:变量适配器可能尚未初始化

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

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

Error:(82, 49) error: 找不到符号方法getCheckedItems()

这是因为适配器的声明类型是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;

【讨论】:

我已经将它投射到我的自定义适配器上,现在它可以完美运行了!也非常感谢您对代码样式和简化实例的建议。从现在开始,我将尝试应用这些规则。通常我使用这个前缀来引用类中声明的对象,这样我就可以将它们与相关方法中声明的对象区分开来,从而使代码更具可读性,但实际上是相同的。 太好了,很高兴为您提供帮助:)

以上是关于在Android中按下提交按钮时使用自定义适配器从列表视图中获取选定项目的主要内容,如果未能解决你的问题,请参考以下文章

如何在基本适配器中按下按钮时添加新项目

在android中按下后退按钮后如何返回相同的选项卡?

XCTestCase:无法在导航栏中按下自定义栏按钮

在自定义 UITableViewCell 中按下 UIButton 时如何获取 indexPathForSelectedRow

确定在 Swift 的自定义 listView 单元格中按下了哪个按钮

当按下 menuItem 以在 android 中显示用于列表视图的自定义适配器时,应用程序崩溃