在 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 布局文件中的提交按钮时获取已检查项目的完整列表,因此我执行以下步骤来消除此问题:
在我的自定义适配器 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;
}
}
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;
)
我已经创建了自己的适配器 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 布局文件中的提交按钮时获取已检查项目的完整列表,因此我执行以下步骤来消除此问题:
在我的自定义适配器 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; } }
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;
)