【问题标题】:Get Selected Item Using Checkbox in Listview使用 Listview 中的复选框获取所选项目
【发布时间】:2023-04-08 11:55:01
【问题描述】:

我正在创建一个 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);

        }


}

【问题讨论】:

  • 您可以为此目的使用稀疏布尔数组。
  • 您是否希望在单击按钮时复选框选中行中的项目?因为你的标题说“当我单击按钮时,使用 Listview 中的复选框获取所选项目”。

标签: android listview


【解决方案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_width="match_parent"
    android:layout_height="match_parent"
    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_width="fill_parent"
        android:id="@+id/listApplication"
        android:layout_height="fill_parent"
        android:layout_above="@+id/button1"
        android:text="@string/hello_world" />

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        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(在我的情况下为ListFragmentonListItemClick 事件中控制复选框状态。

这是示例 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_width="match_parent"
        android:layout_height="50dp"
        android:id="@+id/source_container"
        >
        <ImageView
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:id="@+id/menu_source_icon"
            android:background="@drawable/bla"
            android:layout_margin="5dp"
            />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            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_width="40dp"
            android:layout_height="match_parent"
            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_width="fill_parent"
          android:layout_height="fill_parent">
        
          <TextView android:id="@+id/rowTextView" 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:textSize="16sp" >
          </TextView>
        
          <CheckBox android:id="@+id/CheckBox01" 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            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”

          1. 只需使用 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);
            
               }
            
            }
            
          2. 在复选框的 xml 代码中,只需输入“android:onClick="your method""属性即可。

                 <CheckBox
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        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" />
            
          3. 在你的类中实现那个方法“你的方法”。

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

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2012-08-09
                • 2011-05-29
                • 1970-01-01
                • 1970-01-01
                • 2011-07-02
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多