Android CheckBox

时间:2020-02-23 14:28:49  来源:igfitidea点击:

今天,我们将在ListView中实现android复选框。
如果您尚未使用"自定义适配器"实现ListView,请参阅此处。

Android复选框

下图显示了我们的android复选框示例应用程序的项目结构。

Android Checkbox示例

下面给出了" activity_main.xml"布局文件的代码。

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="https://schemas.android.com/apk/res/android"
  xmlns:tools="https://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context="com.theitroad.listviewwithcheckboxes.MainActivity">

  <ListView
      android:id="@+id/listView"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"

</android.support.constraint.ConstraintLayout>

列表中每一行的布局在下面的" row_item.xml"中定义。

<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
  android:padding="10dp"
  android:layout_width="match_parent"
  android:layout_height="wrap_content">

  <TextView
      android:id="@+id/txtName"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_alignParentLeft="true"
      android:layout_alignParentStart="true"
      android:layout_centerVertical="true"
      android:textSize="16sp" 

  <CheckBox
      android:id="@+id/checkBox"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_alignParentEnd="true"
      android:layout_alignParentRight="true"
      android:layout_alignParentTop="true" 

</RelativeLayout>

ListView的DataModel.java类的定义如下所示。

package com.theitroad.listviewwithcheckboxes;

public class DataModel {

  public String name;
  boolean checked;

  DataModel(String name, boolean checked) {
      this.name = name;
      this.checked = checked;

  }
}

布尔参数checked将用于选中和取消选中复选框。

MainActivity.java类文件如下。

package com.theitroad.listviewwithcheckboxes;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

  ArrayList dataModels;
  ListView listView;
  private CustomAdapter adapter;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);

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

      dataModels = new ArrayList();

      dataModels.add(new DataModel("Apple Pie", false));
      dataModels.add(new DataModel("Banana Bread", false));
      dataModels.add(new DataModel("Cupcake", false));
      dataModels.add(new DataModel("Donut", true));
      dataModels.add(new DataModel("Eclair", true));
      dataModels.add(new DataModel("Froyo", true));
      dataModels.add(new DataModel("Gingerbread", true));
      dataModels.add(new DataModel("Honeycomb", false));
      dataModels.add(new DataModel("Ice Cream Sandwich", false));
      dataModels.add(new DataModel("Jelly Bean", false));
      dataModels.add(new DataModel("Kitkat", false));
      dataModels.add(new DataModel("Lollipop", false));
      dataModels.add(new DataModel("Marshmallow", false));
      dataModels.add(new DataModel("Nougat", false));

      adapter = new CustomAdapter(dataModels, getApplicationContext());

      listView.setAdapter(adapter);
      listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
          @Override
          public void onItemClick(AdapterView parent, View view, int position, long id) {

              DataModel dataModel= dataModels.get(position);
              dataModel.checked = !dataModel.checked;
              adapter.notifyDataSetChanged();

          }
      });
  }
}

在上面的代码中,我们将DataModels对象的ArrayList设置为适配器。
每当调用ListView Click侦听器时,我们都会反转相应行的检查值,并调用notifyDataSetChanged()来更新适配器类中的更改。

下面给出了ListView的CustomAdapter.java类文件。

package com.theitroad.listviewwithcheckboxes;

import android.content.Context;
import android.support.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.TextView;

import java.util.ArrayList;

public class CustomAdapter extends ArrayAdapter {

  private ArrayList dataSet;
  Context mContext;

  //View lookup cache
  private static class ViewHolder {
      TextView txtName;
      CheckBox checkBox;
  }

  public CustomAdapter(ArrayList data, Context context) {
      super(context, R.layout.row_item, data);
      this.dataSet = data;
      this.mContext = context;

  }
  @Override
  public int getCount() {
      return dataSet.size();
  }

  @Override
  public DataModel getItem(int position) {
      return dataSet.get(position);
  }

  @Override
  public View getView(int position, View convertView, @NonNull ViewGroup parent) {

      ViewHolder viewHolder;
      final View result;

      if (convertView == null) {
          viewHolder = new ViewHolder();
          convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_item, parent, false);
          viewHolder.txtName = (TextView) convertView.findViewById(R.id.txtName);
          viewHolder.checkBox = (CheckBox) convertView.findViewById(R.id.checkBox);

          result=convertView;
          convertView.setTag(viewHolder);

      } else {
          viewHolder = (ViewHolder) convertView.getTag();
          result=convertView;
      }

      DataModel item = getItem(position);

      viewHolder.txtName.setText(item.name);
      viewHolder.checkBox.setChecked(item.checked);

      return result;
  }
}

让我们看看运行上述应用程序时的输出。

如果到目前为止,您已尝试运行该应用程序,则应看到单击任何行都不会突出显示该行,也不会更改检查状态。
仅当您专门单击复选框时,它才会切换。
我们的目标是使复选框成为ListView行布局的一部分,而不是让其独立运行。
发生此冲突的原因是:

Android CheckBox类具有其自己的单击和检查侦听器集。
为了避免它们与ListView侦听器之间的干扰,我们在xml的CheckBox小部件中设置了以下属性。

  • android:focusable =" false""
  • android:focusableInTouchMode =" false""
  • android:clickable =" false""

这些将使CheckBoxes既不可单击也不可聚焦,从而使ListView行单击正确运行。

<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
  android:padding="10dp"
  android:layout_width="match_parent"
  android:layout_height="wrap_content">

  <TextView
      android:id="@+id/txtName"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_alignParentLeft="true"
      android:layout_alignParentStart="true"
      android:layout_centerVertical="true"
      android:textSize="16sp" 

  <CheckBox
      android:id="@+id/checkBox"
      android:clickable="false"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_alignParentEnd="true"
      android:layout_alignParentRight="true"
      android:layout_alignParentTop="true"
      android:focusable="false"
      android:focusableInTouchMode="false" 

</RelativeLayout>