ListView+checkBox删除需求实现以及注意事项

本文介绍了在Android应用开发中,如何实现ListView结合CheckBox的删除功能。讨论了自定义条目布局和Adapter的重要性,特别强调了`android:descendantFocusability="blocksDescendants"`属性在防止点击事件失效中的关键作用。此外,还提醒开发者在处理删除操作时,务必清空选中状态的列表集合以避免错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、概述

一般项目都会有删除的功能,一般都会用到checkbox,通过点击checkbox选择要选择的条目,并且item也可以点击,点击后,可以进到条目的详情,例如新闻类似的。

二、效果截图



三、实现过程

1、自定义条目layout( android:descendantFocusability="blocksDescendants"此属性比较重要,最后总结会提到

 <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:descendantFocusability="blocksDescendants"
    android:padding="10dp" >

    <TextView
        android:id="@+id/id_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:padding="10dp"
        android:textColor="@android:color/black"
        android:textIsSelectable="true"
        android:textSize="15sp" >
    </TextView>

    <CheckBox
        android:id="@+id/id_checkbox"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true" />

</RelativeLayout>

2、自定义adapter(ViewHolder,就绑定的两个控件,代码就不贴出了)

@Override
		public View getView(final int position, View convertView,
				ViewGroup parent)
		{
			ViewHolder holder = null;
			if (convertView == null)
			{
				convertView = View.inflate(context,
						R.layout.listview_item, null);
				holder = new ViewHolder();
				holder.textView = (TextView) convertView
						.findViewById(R.id.id_text);
				holder.checkBox = (CheckBox) convertView
						.findViewById(R.id.id_checkbox);
				convertView.setTag(holder);
			} else
			{
				holder = (ViewHolder) convertView.getTag();
			}

			holder.textView.setText(list.get(position).get("itemTitle"));
			if ("No".equals(list.get(position).get("isChecked")))
			{
				holder.checkBox.setChecked(false);
			} else
			{
				holder.checkBox.setChecked(true);
			}
			/**
			 * 这里一定要处理checkbox的点击事件而非setOnCheckedChangeListener,那样做不起作用会出错
			 */
			holder.checkBox.setOnClickListener(new OnClickListener()
			{

				@Override
				public void onClick(View v)
				{
					CheckBox checkBox = (CheckBox) v
							.findViewById(R.id.id_checkbox);
					if ("No".equals(list.get(position).get("isChecked")))
					{
						//通过点击改变选中状态以及改变list里面相应的值
						checkBox.setChecked(true);
						list.get(position).put("isChecked", "Yes");

					} else
					{

						checkBox.setChecked(false);
						list.get(position).put("isChecked", "No");
					}
					//然后再更新界面就可以了
					notifyDataSetChanged();
				}
			});
			return convertView;
		}
3、全选点击事件:

selectAll.setOnClickListener(new OnClickListener()
		{

			@Override
			public void onClick(View v)
			{
				if (isSelectAll)
				{
					isSelectAll = false;
					selectAll.setText("全选");
					for (Map<String, String> map : list)
					{
						map.put("isChecked", "No");
					}

				} else
				{
					isSelectAll = true;
					selectAll.setText("全不选");
					for (Map<String, String> map : list)
					{
						map.put("isChecked", "Yes");
					}

				}
				adapter.notifyDataSetChanged();
			}
		});
4、delete按钮点击事件

// 删除按钮点击事件
		delete.setOnClickListener(new OnClickListener()
		{

			@Override
			public void onClick(View v)
			{
				// 注意点:在每次点击时清除存取正在被选中的item position,要不然,每次点击可能会重复添加
				selectedPositiones.clear();
				for (int i = 0; i < list.size(); i++)
				{
					if ("Yes".equals(list.get(i).get("isChecked")))
					{
						Map<String, Integer> map = new HashMap<String, Integer>();
						map.put("selectedPosition", i);
						selectedPositiones.add(map);
					}
				}
				// 当存取已选择的条目集合大于0时,展示dialog对话框,反之提醒用户选择想要删除的条目
				if (selectedPositiones.size() > 0)
					initMyDialog();
				else
					Toast.makeText(context, "请选择您要删除的项目!", Toast.LENGTH_SHORT)
							.show();

			}

		});

5、删除方法

private void deleteWay()
	{
		if (isSelectAll)
		{
			// 删除全部
			list.clear();
			Toast.makeText(context, "全部删除成功", Toast.LENGTH_SHORT).show();
		} else
		{
			// 删除单个或一组,倒叙以此删除,可以避免并发修改异常
			for (int i = list.size() - 1; i > -1; i--)
			{
				if ("Yes".equals(list.get(i).get("isChecked")))
				{
					list.remove(i);
				}
			}

		}
		adapter.notifyDataSetChanged();
	}
6、dialog加载方式参考我的另一篇文章《圆角dialog》

四、总结以及注意点

注意:

1、 android:descendantFocusability="blocksDescendants"   这个属性很重要,需要在listview_item.xml根控件添加,如果不添加,会造成setOnItemclickListener事件失效,那为什么会这样呢?

      是因为item里面如果有button或者checkbox他们会优先抢占焦点,所以listview的item点击事件就无法发生效用,这个属性又是什么意思呢?

属性的值有三种:

        beforedescendants:viewgroup会优先其子类控件而获取到焦点

        afterdescendants:viewgroup只有当其子类控件不需要获取焦点时才获取焦点

        blocksdescendants:viewgroup会覆盖子类控件而直接获得焦点

而我们选择的第三个,就可以解决我们的问题

2、注意的点就是每次点击时用于存取是否选中的list集合都要先清空,要不然就会出错

总结:计算机思维方式很重要,继续努力吧,有问题随时问我


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值