使用 Listview 中的复选框获取所选项目
Posted
技术标签:
【中文标题】使用 Listview 中的复选框获取所选项目【英文标题】:Get Selected Item Using Checkbox in Listview 【发布时间】:2013-08-12 08:15:56 【问题描述】:我正在创建一个 android 应用程序,其中有一个 ListView,它显示了我手机中安装的所有应用程序。
我的ListView是自定义的,它包含了一个Icon、TextView和CheckBox,图标的用途是显示应用的图标,TextView是显示应用的名称,CheckBox的用途是确定我在 ListView 中选择了什么项目。
当我单击应用程序中的按钮时,如何确定在 ListView 行中选择的 CheckBox 是什么?我是 Android 新手,所以我不知道我应该采取什么方法。
这是我的代码:
public class AppInfo
public Drawable icon;
public String applicationName;
public AppInfo()
super();
public AppInfo(Drawable icon, String applicationName)
super();
this.icon = icon;
this.applicationName = applicationName;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import android.app.Activity;
import android.widget.CheckBox;
public class AppInfoAdapter extends ArrayAdapter<AppInfo>
Context context;
int layoutResourceId;
AppInfo data[] = null;
public AppInfoAdapter(Context context, int layoutResourceId, AppInfo[] data)
super(context, layoutResourceId,data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
@Override
public View getView(int position, View convertView, ViewGroup parent)
View row = convertView;
AppInfoHolder holder= null;
if (row == null)
LayoutInflater inflater = ((Activity)context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new AppInfoHolder();
holder.imgIcon = (ImageView) row.findViewById(R.id.imgPackageIcon);
holder.txtTitle = (TextView) row.findViewById(R.id.txtApplicationName);
holder.chkSelect = (CheckBox) row.findViewById(R.id.chkSelect);
row.setTag(holder);
else
holder = (AppInfoHolder)row.getTag();
AppInfo appinfo = data[position];
holder.txtTitle.setText(appinfo.applicationName);
holder.imgIcon.setImageDrawable(appinfo.icon);
holder.chkSelect.setChecked(true);
return row;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.CheckBox;
public class AppInfoHolder
ImageView imgIcon;
TextView txtTitle;
CheckBox chkSelect;
import android.app.Activity;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
import android.content.pm.PackageInfo;
public class CacheActivity extends Activity
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cache);
final ListView listApplication = (ListView)findViewById(R.id.listApplication);
ApplicationInfo applicationInfo = getApplicationInfo();
PackageManager pm = getPackageManager();
List<PackageInfo> pInfo = new ArrayList<PackageInfo>();
pInfo.addAll(pm.getInstalledPackages(0));
AppInfo app_info[] = new AppInfo[pInfo.size()];
int counter = 0;
for(PackageInfo item: pInfo)
try
applicationInfo = pm.getApplicationInfo(item.packageName, 1);
app_info[counter] = new AppInfo(pm.getApplicationIcon(applicationInfo),
String.valueOf(pm.getApplicationLabel(applicationInfo)));
System.out.println(counter);
catch(Exception e)
System.out.println(e.getMessage());
counter++;
AppInfoAdapter adapter = new AppInfoAdapter(this, R.layout.listview_item_row, app_info);
listApplication.setAdapter(adapter);
【问题讨论】:
您可以为此目的使用稀疏布尔数组。 您是否希望在单击按钮时复选框选中行中的项目?因为你的标题说“当我单击按钮时,”。 【参考方案1】:假设您想要获取在单击按钮时选中复选框的行中的项目。基于您的标题“当我单击按钮时使用 Listview 中的复选框获取所选项目”的假设。
试试下面的。仅进行如下更改。其余部分保持不变。
题目解释与讨论@
https://groups.google.com/forum/?fromgroups#!topic/android-developers/No0LrgJ6q2M
MainActivity.java
public class MainActivity extends Activity
AppInfoAdapter adapter ;
AppInfo app_info[] ;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ListView listApplication = (ListView)findViewById(R.id.listApplication);
Button b= (Button) findViewById(R.id.button1);
b.setOnClickListener(new OnClickListener()
@Override
public void onClick(View v)
// TODO Auto-generated method stub
StringBuilder result = new StringBuilder();
for(int i=0;i<adapter.mCheckStates.size();i++)
if(adapter.mCheckStates.get(i)==true)
result.append(app_info[i].applicationName);
result.append("\n");
Toast.makeText(MainActivity.this, result, 1000).show();
);
ApplicationInfo applicationInfo = getApplicationInfo();
PackageManager pm = getPackageManager();
List<PackageInfo> pInfo = new ArrayList<PackageInfo>();
pInfo.addAll(pm.getInstalledPackages(0));
app_info = new AppInfo[pInfo.size()];
int counter = 0;
for(PackageInfo item: pInfo)
try
applicationInfo = pm.getApplicationInfo(item.packageName, 1);
app_info[counter] = new AppInfo(pm.getApplicationIcon(applicationInfo),
String.valueOf(pm.getApplicationLabel(applicationInfo)));
System.out.println(counter);
catch(Exception e)
System.out.println(e.getMessage());
counter++;
adapter = new AppInfoAdapter(this, R.layout.listview_item_row, app_info);
listApplication.setAdapter(adapter);
activity_main.xml 带有按钮的 ListView
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_
android:layout_
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<ListView
android:layout_
android:id="@+id/listApplication"
android:layout_
android:layout_above="@+id/button1"
android:text="@string/hello_world" />
<Button
android:id="@+id/button1"
android:layout_
android:layout_
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:text="Button" />
</RelativeLayout>
AppInfoAdapter
public class AppInfoAdapter extends ArrayAdapter<AppInfo> implements CompoundButton.OnCheckedChangeListener
SparseBooleanArray mCheckStates;
Context context;
int layoutResourceId;
AppInfo data[] = null;
public AppInfoAdapter(Context context, int layoutResourceId, AppInfo[] data)
super(context, layoutResourceId,data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
mCheckStates = new SparseBooleanArray(data.length);
@Override
public View getView(int position, View convertView, ViewGroup parent)
View row = convertView;
AppInfoHolder holder= null;
if (row == null)
LayoutInflater inflater = ((Activity)context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new AppInfoHolder();
holder.imgIcon = (ImageView) row.findViewById(R.id.imageView1);
holder.txtTitle = (TextView) row.findViewById(R.id.textView1);
holder.chkSelect = (CheckBox) row.findViewById(R.id.checkBox1);
row.setTag(holder);
else
holder = (AppInfoHolder)row.getTag();
AppInfo appinfo = data[position];
holder.txtTitle.setText(appinfo.applicationName);
holder.imgIcon.setImageDrawable(appinfo.icon);
// holder.chkSelect.setChecked(true);
holder.chkSelect.setTag(position);
holder.chkSelect.setChecked(mCheckStates.get(position, false));
holder.chkSelect.setOnCheckedChangeListener(this);
return row;
public boolean isChecked(int position)
return mCheckStates.get(position, false);
public void setChecked(int position, boolean isChecked)
mCheckStates.put(position, isChecked);
public void toggle(int position)
setChecked(position, !isChecked(position));
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked)
mCheckStates.put((Integer) buttonView.getTag(), isChecked);
static class AppInfoHolder
ImageView imgIcon;
TextView txtTitle;
CheckBox chkSelect;
这是快照
【讨论】:
如果您只检查最后一个,它是否显示该项目 toast ? @RanjitPati 这是一个工作代码。这没有问题。如果您有问题,请发布新问题而不是评论。如果没有看到代码,我无法猜测或建议出了什么问题 你能告诉你在哪里使用toggle
吗?
@Raghunandan 在上面的代码中没有被调用:)
CompoundButton 类型中的方法 setOnCheckedChangeListener(CompoundButton.OnCheckedChangeListener) 不适用于在此行上出现此错误的参数 (CacheBoostAdapter) deleteBox.setOnCheckedChangeListener(this);【参考方案2】:
这是一个简化但很容易... 您需要将可聚焦标志添加到复选框,如前所述。 您还需要添加可点击标志,如下所示:
android:focusable="false"
android:clickable="false"
您可以从ListView
(在我的情况下为ListFragment
)onListItemClick
事件中控制复选框状态。
这是示例 onListItemClick 方法:
public void onListItemClick(ListView l, View v, int position, long id)
super.onListItemClick(l, v, position, id);
//Get related checkbox and change flag status..
CheckBox cb = (CheckBox)v.findViewById(R.id.rowDone);
cb.setChecked(!cb.isChecked());
Toast.makeText(getActivity(), "Click item", Toast.LENGTH_SHORT).show();
【讨论】:
在这种情况下,Lollipop 及更高版本的动画效果会消失【参考方案3】:您必须在列表视图中添加一个 OnItemClickListener 以确定单击了哪个项目,然后找到复选框。
mListView.setOnItemClickListener(new OnItemClickListener()
@Override
public void onItemClick(AdapterView<?> parent, View v, int position, long id)
CheckBox cb = (CheckBox) v.findViewById(R.id.checkbox_id);
);
【讨论】:
【参考方案4】:我有类似的问题。提供的 xml 示例作为单个 ListViewItem 放置,我无法单击 Item 本身,但复选框正在工作。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_
android:layout_
android:id="@+id/source_container"
>
<ImageView
android:layout_
android:layout_
android:id="@+id/menu_source_icon"
android:background="@drawable/bla"
android:layout_margin="5dp"
/>
<TextView
android:layout_
android:layout_
android:id="@+id/menu_source_name"
android:text="Test"
android:textScaleX="1.5"
android:textSize="20dp"
android:padding="8dp"
android:layout_weight="1"
android:layout_gravity="center_vertical"
android:textColor="@color/source_text_color"/>
<CheckBox
android:layout_
android:layout_
android:id="@+id/menu_source_check_box"/>
</LinearLayout>
解决方案:添加属性
android:focusable="false"
到 CheckBox 控件。
【讨论】:
【参考方案5】:使复选框不可聚焦,并在列表项上单击执行此操作, 这里codevalue是位置。
Arraylist<Integer> selectedschools=new Arraylist<Integer>();
lvPickSchool.setOnItemClickListener(new AdapterView.OnItemClickListener()
@Override
public void onItemClick(AdapterView<?> parent, View view, int codevalue, long id)
CheckBox cb = (CheckBox) view.findViewById(R.id.cbVisitingStatus);
cb.setChecked(!cb.isChecked());
if(cb.isChecked())
if(!selectedschool.contains(codevaule))
selectedschool.add(codevaule);
else
if(selectedschool.contains(codevaule))
selectedschool.remove(codevaule);
);
【讨论】:
【参考方案6】:[带复选框的自定义 ListView]
如果customlayout使用checkbox,则必须设置checkbox focusable = false
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_
android:layout_>
<TextView android:id="@+id/rowTextView"
android:layout_
android:layout_
android:padding="10dp"
android:textSize="16sp" >
</TextView>
<CheckBox android:id="@+id/CheckBox01"
android:layout_
android:layout_
android:padding="10dp"
android:layout_alignParentRight="true"
android:layout_marginRight="6sp"
android:focusable="false"> // <---important
</CheckBox>
</RelativeLayout>
阅读更多:A ListView with Checkboxes (Without Using ListActivity)
【讨论】:
【参考方案7】:“复选框的用途是确定我选择了Listview中的什么Item”
只需使用 Adapter 类中的 setTag() 方法将标签添加到复选框。另一方使用 getTag() 方法。
@Override
public void onBindViewHolder(MyViewHolder holder, int position)
ServiceHelper helper=userServices.get(position);
holder.tvServiceName.setText(helper.getServiceName());
if(!helper.isServiceStatus())
holder.btnAdd.setVisibility(View.VISIBLE);
holder.btnAdd.setTag(helper.getServiceName());
holder.checkBoxServiceStatus.setVisibility(View.INVISIBLE);
else
holder.checkBoxServiceStatus.setVisibility(View.VISIBLE);
//This Line
holder.checkBoxServiceStatus.setTag(helper.getServiceName());
holder.btnAdd.setVisibility(View.INVISIBLE);
在复选框的 xml 代码中,只需输入“android:onClick="your method""属性即可。
<CheckBox
android:layout_
android:layout_
android:onClick="checkboxClicked"
android:id="@+id/checkBox_Service_row"
android:layout_marginRight="5dp"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
在你的类中实现那个方法“你的方法”。
protected void checkboxClicked(View view)
CheckBox checkBox=(CheckBox) view;
String tagName="";
if(checkBox.isChecked())
tagName=checkBox.getTag().toString();
deleteServices.add(tagName);
checkboxArrayList.add(checkBox);
else
checkboxArrayList.remove(checkBox);
tagName=checkBox.getTag().toString();
if(deleteServices.size()>0&&deleteServices.contains(tagName))
deleteServices.remove(tagName);
【讨论】:
【参考方案8】:完整参考存在于:listview with checkbox android studio 将所选项目传递给下一个活动
主要源码如下。
先创建一个模型类
public class Model
private boolean isSelected;
private String animal;
public String getAnimal()
return animal;
public void setAnimal(String animal)
this.animal = animal;
public boolean getSelected()
return isSelected;
public void setSelected(boolean selected)
isSelected = selected;
然后在适配器类中,将标签设置为复选框。在复选框的 onclicklistener 中使用这些标签。
public class CustomAdapter extends BaseAdapter
private Context context;
public static ArrayList<Model> modelArrayList;
public CustomAdapter(Context context, ArrayList<Model> modelArrayList)
this.context = context;
this.modelArrayList = modelArrayList;
@Override
public int getViewTypeCount()
return getCount();
@Override
public int getItemViewType(int position)
return position;
@Override
public int getCount()
return modelArrayList.size();
@Override
public Object getItem(int position)
return modelArrayList.get(position);
@Override
public long getItemId(int position)
return 0;
@Override
public View getView(int position, View convertView, ViewGroup parent)
final ViewHolder holder;
if (convertView == null)
holder = new ViewHolder(); LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.lv_item, null, true);
holder.checkBox = (CheckBox) convertView.findViewById(R.id.cb);
holder.tvAnimal = (TextView) convertView.findViewById(R.id.animal);
convertView.setTag(holder);
else
// the getTag returns the viewHolder object set as a tag to the view
holder = (ViewHolder)convertView.getTag();
holder.checkBox.setText("Checkbox "+position);
holder.tvAnimal.setText(modelArrayList.get(position).getAnimal());
holder.checkBox.setChecked(modelArrayList.get(position).getSelected());
holder.checkBox.setTag(R.integer.btnplusview, convertView);
holder.checkBox.setTag( position);
holder.checkBox.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
View tempview = (View) holder.checkBox.getTag(R.integer.btnplusview);
TextView tv = (TextView) tempview.findViewById(R.id.animal);
Integer pos = (Integer) holder.checkBox.getTag();
Toast.makeText(context, "Checkbox "+pos+" clicked!", Toast.LENGTH_SHORT).show();
if(modelArrayList.get(pos).getSelected())
modelArrayList.get(pos).setSelected(false);
else
modelArrayList.get(pos).setSelected(true);
);
return convertView;
private class ViewHolder
protected CheckBox checkBox;
private TextView tvAnimal;
【讨论】:
【参考方案9】:您可以使用 model 类并使用 setTag() getTag() 方法来跟踪列表视图中的哪些项目已检查,哪些未检查.
更多参考:listview with checkbox in android
模型源代码
public class Model
private boolean isSelected;
private String animal;
public String getAnimal()
return animal;
public void setAnimal(String animal)
this.animal = animal;
public boolean getSelected()
return isSelected;
public void setSelected(boolean selected)
isSelected = selected;
将其放入您的自定义适配器中
holder.checkBox.setTag(R.integer.btnplusview, convertView);
holder.checkBox.setTag( position);
holder.checkBox.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
View tempview = (View) holder.checkBox.getTag(R.integer.btnplusview);
TextView tv = (TextView) tempview.findViewById(R.id.animal);
Integer pos = (Integer) holder.checkBox.getTag();
Toast.makeText(context, "Checkbox "+pos+" clicked!", Toast.LENGTH_SHORT).show();
if(modelArrayList.get(pos).getSelected())
modelArrayList.get(pos).setSelected(false);
else
modelArrayList.get(pos).setSelected(true);
);
customAdapter 的完整代码是
public class CustomAdapter extends BaseAdapter
private Context context;
public static ArrayList<Model> modelArrayList;
public CustomAdapter(Context context, ArrayList<Model> modelArrayList)
this.context = context;
this.modelArrayList = modelArrayList;
@Override
public int getViewTypeCount()
return getCount();
@Override
public int getItemViewType(int position)
return position;
@Override
public int getCount()
return modelArrayList.size();
@Override
public Object getItem(int position)
return modelArrayList.get(position);
@Override
public long getItemId(int position)
return 0;
@Override
public View getView(int position, View convertView, ViewGroup parent)
final ViewHolder holder;
if (convertView == null)
holder = new ViewHolder(); LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.lv_item, null, true);
holder.checkBox = (CheckBox) convertView.findViewById(R.id.cb);
holder.tvAnimal = (TextView) convertView.findViewById(R.id.animal);
convertView.setTag(holder);
else
// the getTag returns the viewHolder object set as a tag to the view
holder = (ViewHolder)convertView.getTag();
holder.checkBox.setText("Checkbox "+position);
holder.tvAnimal.setText(modelArrayList.get(position).getAnimal());
holder.checkBox.setChecked(modelArrayList.get(position).getSelected());
holder.checkBox.setTag(R.integer.btnplusview, convertView);
holder.checkBox.setTag( position);
holder.checkBox.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
View tempview = (View) holder.checkBox.getTag(R.integer.btnplusview);
TextView tv = (TextView) tempview.findViewById(R.id.animal);
Integer pos = (Integer) holder.checkBox.getTag();
Toast.makeText(context, "Checkbox "+pos+" clicked!", Toast.LENGTH_SHORT).show();
if(modelArrayList.get(pos).getSelected())
modelArrayList.get(pos).setSelected(false);
else
modelArrayList.get(pos).setSelected(true);
);
return convertView;
private class ViewHolder
protected CheckBox checkBox;
private TextView tvAnimal;
【讨论】:
以上是关于使用 Listview 中的复选框获取所选项目的主要内容,如果未能解决你的问题,请参考以下文章
如何从 QComboBox 中获取所选项目以显示在 PyQt5 的 QTableWidget 中? (QComboBox 有复选框来选择项目)
使用android中的自定义arrayadapter在listview中使用复选框检查后如何删除多个项目?