Android的ListView多选删除操作实现代码
最近尝试做了个listview的多选demo,网上看其他人的例子感觉不是很难,自己动手做了下,各种细节问题,没那么简单啊。既然做了,简单写个笔记记录下。
练手demo,命名笔记乱,不要介意哦。
主界面布局activity_main.xml
<relativelayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/rootview" android:paddingbottom="@dimen/activity_vertical_margin" android:paddingleft="@dimen/activity_horizontal_margin" android:paddingright="@dimen/activity_horizontal_margin" android:paddingtop="@dimen/activity_vertical_margin" tools:context="com.example.listchecked.mainactivity" > <listview android:id="@+id/listview1" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginbottom="50dp" > </listview> <linearlayout android:id="@+id/button_group" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignleft="@+id/listview1" android:layout_alignparentbottom="true" android:orientation="vertical" > <button android:id="@+id/del" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="删除" /> </linearlayout> </relativelayout>
列表item的布局
<?xml version="1.0" encoding="utf-8"?> <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" android:descendantfocusability="blocksdescendants" > <!--注意上面这个属性,很关键,不加会导致list无法响应onitemclicklistener中的事件--> <relativelayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" > <checkbox android:id="@+id/checkbox1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:clickable="false" android:focusable="false" /> <imageview android:id="@+id/imageview1" android:layout_width="match_parent" android:layout_height="match_parent" android:scaletype="fitcenter" android:src="@drawable/ic_launcher" /> </relativelayout> <linearlayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:orientation="vertical" > <textview android:id="@+id/title" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="title" android:textsize="20sp" /> <textview android:id="@+id/teacher" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="teacher" /> <textview android:id="@+id/time" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="time" /> <textview android:id="@+id/peoplenum" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="peoplenum" /> </linearlayout> </linearlayout>
这个item的布局就被在细节上坑了一次,item中添加button,checkbox,imagebutton等时,会导致只响应这些控件的事件,item整体的事件就不会响应了,刚开始没有加那条属性,勾选checkbox后,点删除没有反应。这问题要发现也有点难度,之前见大神们推荐过分析布局的工具hierarchyviewer,这个工具,个人感觉和前端开发中的f12类似啊,很方便,可以看到每个布局的情况。也是好奇,点开一看,整个item的布局,从父布局,到子布局,只要checkbox可以接受click,其他全部是false,这就是问题所在了,后来百度了一下,即如上结论。
解决办法就是添加android:descendantfocusability=”blocksdescendants” 到list的item的布局里,添加以后,发现checkbox还是可以被单独点击,不响应list的点击选中事件,很是奇怪,看其他人的例子中就没有这种现象。最后只能设置checkbox不能被点击 android:clickable=”false” 布局问题解决了,下面是java类的源码:
首先是bean类,itembean.java
package com.example.listchecked; public class itembean { private int imgres; private string title,teacher,time; private int peoplenum,id; private boolean ischecked; private boolean isshow; public boolean isshow() { return isshow; } public void setshow(boolean isshow) { this.isshow = isshow; } public int getid() { return id; } public void setid(int id) { this.id = id; } public boolean ischecked() { return ischecked; } public void setchecked(boolean ischecked) { this.ischecked = ischecked; } public int getimgres() { return imgres; } public void setimgres(int img) { this.imgres = img; } public string gettitle() { return title; } public void settitle(string title) { this.title = title; } public string getteacher() { return teacher; } public void setteacher(string teacher) { this.teacher = teacher; } public string gettime() { return time; } public void settime(string time) { this.time = time; } public int getpeoplenum() { return peoplenum; } public void setpeoplenum(int peoplenum) { this.peoplenum = peoplenum; } }
自定义的adapter,mylistadapter.java
package com.example.listchecked; import java.util.list; import android.content.context; import android.view.layoutinflater; import android.view.view; import android.view.viewgroup; import android.widget.baseadapter; import android.widget.checkbox; import android.widget.compoundbutton; import android.widget.compoundbutton.oncheckedchangelistener; import android.widget.imageview; import android.widget.textview; public class mylistadapter extends baseadapter { private layoutinflater inflater; private list<itembean> items; private itembean item; private onshowitemclicklistener onshowitemclicklistener; public mylistadapter(list<itembean> list,context context) { items=list; inflater=layoutinflater.from(context); } @override public int getcount() { // todo 自动生成的方法存根 return items.size(); } @override public object getitem(int position) { // todo 自动生成的方法存根 return items.get(position); } @override public long getitemid(int position) { // todo 自动生成的方法存根 return items.get(position).getid(); } @override public view getview(int position, view convertview, viewgroup parent) { // todo 自动生成的方法存根 viewholder holder;//使用viewholder,大神说能提升性能 if(convertview==null) { holder=new viewholder(); convertview=inflater.inflate(r.layout.item_view, null); holder.img=(imageview) convertview.findviewbyid(r.id.imageview1); holder.cb=(checkbox) convertview.findviewbyid(r.id.checkbox1); holder.title=(textview)convertview.findviewbyid(r.id.title); holder.teacher=(textview) convertview.findviewbyid(r.id.teacher); holder.time=(textview) convertview.findviewbyid(r.id.time); holder.poeple=(textview)convertview.findviewbyid(r.id.peoplenum); convertview.settag(holder); }else { holder=(viewholder) convertview.gettag(); } item=items.get(position); if(item.isshow()) { holder.cb.setvisibility(view.visible); } else { holder.cb.setvisibility(view.gone); } holder.img.setimageresource(item.getimgres()); holder.title.settext(item.gettitle()); holder.teacher.settext("主讲:"+item.getteacher()); holder.time.settext("课时:"+item.gettime()+"讲"); holder.poeple.settext("学习人数:"+item.getpeoplenum()); holder.cb.setoncheckedchangelistener(new oncheckedchangelistener() { @override public void oncheckedchanged(compoundbutton buttonview, boolean ischecked) { if(ischecked) { item.setchecked(true); } else { item.setchecked(false); } //回调方法,讲item加入已选择的 onshowitemclicklistener.onshowitemclick(item); } }); //监听后设置选择状态 holder.cb.setchecked(item.ischecked()); return convertview; } static class viewholder { imageview img; checkbox cb; textview title,teacher,time,poeple; } public interface onshowitemclicklistener { public void onshowitemclick(itembean bean); } public void setonshowitemclicklistener(onshowitemclicklistener onshowitemclicklistener) { this.onshowitemclicklistener = onshowitemclicklistener; } }
最后是mainactivity.java
package com.example.listchecked; import java.util.arraylist; import java.util.list; import android.app.activity; import android.content.context; import android.os.bundle; import android.util.log; import android.view.layoutinflater; import android.view.view; import android.view.view.onclicklistener; import android.widget.adapterview; import android.widget.adapterview.onitemclicklistener; import android.widget.button; import android.widget.linearlayout; import android.widget.listview; import android.widget.relativelayout; import android.widget.toast; import com.example.listchecked.mylistadapter.onshowitemclicklistener; public class mainactivity extends activity implements onshowitemclicklistener { private listview listview; private list<itembean> datalist,selectedlist; private mylistadapter myadapter; private relativelayout rootview; private linearlayout menuview; private linearlayout openview; private static boolean isshow; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); isshow=false; setcontentview(r.layout.activity_main); button delbtn=(button) findviewbyid(r.id.del); rootview=(relativelayout) findviewbyid(r.id.rootview); menuview=(linearlayout) findviewbyid(r.id.button_group); listview=(listview) findviewbyid(r.id.listview1); datalist=new arraylist<itembean>(); selectedlist=new arraylist<itembean>(); for(int i=0;i<10;i++) { itembean item=new itembean(); item.setid(i); item.setimgres(r.drawable.ic_launcher); item.settitle("第"+item.getid()+"个"); item.setteacher("杨老师"); item.settime("34"); item.setpeoplenum(i+1*100); item.setchecked(false); item.setshow(isshow); datalist.add(item); } myadapter=new mylistadapter(datalist, this); myadapter.setonshowitemclicklistener(mainactivity.this); listview.setadapter(myadapter); delbtn.setonclicklistener(new onclicklistener() { @override public void onclick(view v) { // todo 自动生成的方法存根 showmenu(); isshow=true; selectedlist.clear(); for(itembean item:datalist) { item.setshow(isshow); } myadapter.notifydatasetchanged(); } }); listview.setonitemclicklistener(new onitemclicklistener() { @override public void onitemclick(adapterview<?> parent, view view, int position, long id) { // todo 自动生成的方法存根 if (isshow) { itembean item = datalist.get(position); boolean ischecked = item.ischecked(); if (ischecked) { item.setchecked(false); } else { item.setchecked(true); } myadapter.notifydatasetchanged(); log.d("select",selectedlist.size()+""); } } }); } //显示选择删除等的菜单 private void showmenu() { relativelayout.layoutparams lp=new relativelayout.layoutparams(relativelayout.layoutparams.match_parent, relativelayout.layoutparams.wrap_content); lp.addrule(relativelayout.align_parent_bottom); layoutinflater inflater = (layoutinflater) this.getsystemservice(context.layout_inflater_service); openview=(linearlayout) inflater.inflate(r.layout.delmenu_layout, null); rootview.removeview(menuview); rootview.addview(openview,lp); final button sbtn=(button) openview.findviewbyid(r.id.selectall); button dbtn=(button) openview.findviewbyid(r.id.del_button); button cbtn= (button) openview.findviewbyid(r.id.cancel_button); sbtn.setonclicklistener(new onclicklistener() { @override public void onclick(view v) { // todo 自动生成的方法存根 if ("全选".equals(sbtn.gettext().tostring())) { for (itembean bean : datalist) { if (!bean.ischecked()) { bean.setchecked(true); if (!selectedlist.contains(bean)) { selectedlist.add(bean); } } } myadapter.notifydatasetchanged(); sbtn.settext("反选"); } else if ("反选".equals(sbtn.gettext().tostring())) { for (itembean bean : datalist) { bean.setchecked(false); if (!selectedlist.contains(bean)) { selectedlist.remove(bean); } } myadapter.notifydatasetchanged(); sbtn.settext("全选"); } } }); dbtn.setonclicklistener(new onclicklistener() { @override public void onclick(view v) { // todo 自动生成的方法存根 if (selectedlist!=null && selectedlist.size()>0) { datalist.removeall(selectedlist); myadapter.notifydatasetchanged(); selectedlist.clear(); } else { toast.maketext(mainactivity.this, "请选择条目", toast.length_short).show(); } } }); cbtn.setonclicklistener(new onclicklistener() { @override public void onclick(view v) { // todo 自动生成的方法存根 if (isshow) { selectedlist.clear(); for (itembean bean : datalist) { bean.setchecked(false); bean.setshow(false); } myadapter.notifydatasetchanged(); isshow = false; restoreview(); } } }); } @override public void onshowitemclick(itembean bean) { // todo 自动生成的方法存根 if (bean.ischecked() && !selectedlist.contains(bean)) { selectedlist.add(bean); } else if (!bean.ischecked() && selectedlist.contains(bean)) { selectedlist.remove(bean); } } private void restoreview() { rootview.addview(menuview); if(openview!=null) { rootview.removeview(openview); openview=null; } } }
最后还有那个小菜单的布局,还是放上吧
<?xml version="1.0" encoding="utf-8"?> <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" > <button android:id="@+id/selectall" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="全选" /> <button android:id="@+id/del_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="删除" /> <button android:id="@+id/cancel_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="取消" /> </linearlayout>
全部代码都放上了,如果不想复制粘贴,github地址:https://github.com/2767321434/listchecked
以上就是本文的全部内容,希望对大家学习android软件编程有所帮助。
下一篇: Java添加事件监听的四种方法代码实例
推荐阅读
-
Android的ListView多选删除操作实现代码
-
Android App中ListView仿QQ实现滑动删除效果的要点解析
-
Android实现带有删除按钮的EditText示例代码
-
Android 中实现ListView滑动隐藏标题栏的代码
-
Android滑动删除数据功能的实现代码
-
Android实现单选与多选对话框的代码
-
Android listview ExpandableListView实现多选,单选,全选,edittext实现批量输入的实例代码
-
Android 中实现ListView滑动隐藏标题栏的代码
-
Android滑动删除数据功能的实现代码
-
Android中ListView下拉刷新的实现代码