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>

