一、概述
一般项目都会有删除的功能,一般都会用到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集合都要先清空,要不然就会出错
总结:计算机思维方式很重要,继续努力吧,有问题随时问我