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>