Android实现通用筛选栏
今天来写一个通用的筛选栏的实现,也是因为之前项目中要好多地方用到筛选栏这么个东西,所以为了之后用起来比较方便,就简单的做了一些封装.废话不多说,看一下效果图:
很多app都有用到这个筛选栏,相信大家也不陌生.
一、需求分析
看到这个筛选栏之后,先来考虑一下布局,在开始接触android时候的我,可能看到这个布局的想法是:筛选栏这个部分,一个linearlayout的横向布局,然后再分为3个部分,每个部分各占比重为1,然后在每个部分中放一个textview和imageview,之后监听每个部分的点击事件,对textview和imageview进行颜色、文字、方向等的处理.确实,这样做能实现功能,不过写起来很麻烦,需要手动的去处理textview和imageview的变化,可能筛选栏多了之后就会乱掉,而且还要花费大量时间去查找修改bug,可能有一个小地方写反了,效果就乱掉了.
所以思考一下,对于筛选栏这个部分,有没有更好的布局设计呢?翻了翻能用的控件,发现checkbox其实用在这里很好用(之前可能对于checkbox的用法,只停留在勾选个对勾这样),怎么说它好用呢,因为checkbox有两种状态(选中和未选中)刚好可以符合需求,选中的时候将字体颜色变为蓝色,并且将图标转换方向和颜色,未选中时重置为起始的样式,并且可以通过设置selector轻松的完成样式的转变.只需管理checkbox的状态即可.
对于弹出框,很简单,自定义一个popwindow就可以了.不过需要注意的是因为需要在弹框弹出的时候,改变背景色的透明度,并且在弹出框消失之后恢复背景色的透明度,所以需要做一些特殊处理,这里打算去监听popwindow的变化来去完成相关处理.
二、代码实现及优化
根据上边的分析,布局设计如下:
<?xml version="1.0" encoding="utf-8"?> <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" tools:context="com.example.junweiliu.filterdemo.mainactivity"> <!--筛选栏--> <linearlayout android:id="@+id/ll_stay_visit_selsect" android:layout_width="match_parent" android:layout_height="40dp" android:background="@color/white" android:gravity="center_vertical" android:orientation="horizontal"> <!--筛选地点--> <linearlayout android:id="@+id/ll_place_tab" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center"> <checkbox android:id="@+id/cb_place" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@null" android:button="@null" android:drawablepadding="10dp" android:drawableright="@drawable/seletor_stock_arrow" android:gravity="center" android:text="地点" android:textcolor="@drawable/selector_text_stock" android:textsize="15sp"/> </linearlayout> <!--筛选类型--> <linearlayout android:id="@+id/ll_type" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center"> <checkbox android:id="@+id/cb_type" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@null" android:button="@null" android:drawablepadding="10dp" android:drawableright="@drawable/seletor_stock_arrow" android:gravity="center" android:text="条件" android:textcolor="@drawable/selector_text_stock" android:textsize="15sp"/> </linearlayout> <!--筛选时间--> <linearlayout android:id="@+id/ll_time" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center"> <checkbox android:id="@+id/cb_time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@null" android:button="@null" android:drawablepadding="10dp" android:drawableright="@drawable/seletor_stock_arrow" android:gravity="center" android:text="时间" android:textcolor="@drawable/selector_text_stock" android:textsize="15sp"/> </linearlayout> </linearlayout> </relativelayout>
设置了3部分,并且每个部分都使用checkbox,checkbox中设置了两个selector,分别是android:drawableright=”@drawable/seletor_stock_arrow” 和android:textcolor=”@drawable/selector_text_stock”
设置如下:
设置箭头样式的seletor_stock_arrow:
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <!--选中的箭头样式--> <item android:drawable="@mipmap/arrow_up_blue" android:state_checked="true" /> <!--未选中的箭头样式--> <item android:drawable="@mipmap/arrow_down_black" android:state_checked="false" /> </selector>
设置文字样式的selector_text_stock:
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:color="@color/gray" android:state_checked="false" /> <item android:color="@color/colorprimary" android:state_checked="true" /> </selector>
实现很简单,来看一下效果:
效果还不错,接下来就是在代码中去管理每个checkbox的状态就可以了.在做这部分之前,先来搞定popwindow,后续需要配合checkbox来使用.
popwindow很简单,继承popupwindow,然后自定义一些样式和布局即可,直接放代码:
commonfilterpop:
package com.example.junweiliu.filterdemo.pop; import android.content.context; import android.graphics.drawable.bitmapdrawable; import android.view.layoutinflater; import android.view.view; import android.view.viewgroup; import android.widget.adapterview; import android.widget.listview; import android.widget.popupwindow; import com.example.junweiliu.filterdemo.r; import com.example.junweiliu.filterdemo.adapter.commpopadapter; import java.util.arraylist; import java.util.list; /** * created by junweiliu on 16/11/7. */ public class commonfilterpop extends popupwindow { /** * 布局填充器 */ private layoutinflater minflater; /** * 上下文 */ private context mcontext; /** * 只显示string类型的数据 */ private list<string> mdatas = new arraylist<>(); /** * pop整体view */ private view popupview; /** * 选择条件的list */ private listview contentlv; /** * 筛选条件选择后的回调 */ adapterview.onitemclicklistener itemclicklistener; /** * 适配器 */ commpopadapter adapter; /** * 构造函数 * * @param context * @param mdatas */ public commonfilterpop(context context, list<string> mdatas) { this.minflater = layoutinflater.from(context); this.mcontext = context; this.mdatas = (mdatas); popupview = minflater.inflate( r.layout.common_popup_list_dialog, null); //设置view this.setcontentview(popupview); //设置弹出窗体的宽高 this.setwidth(viewgroup.layoutparams.match_parent); this.setheight(viewgroup.layoutparams.wrap_content); //初始化控件 initpopview(); this.setfocusable(true); this.settouchable(true); this.setoutsidetouchable(true); this.setbackgrounddrawable(new bitmapdrawable()); //需要动画效果的话可以设置 //this.setanimationstyle(r.style.popupwindowanimation); this.update(); } private void initpopview() { contentlv = (listview) popupview.findviewbyid(r.id.lv_pop); adapter = new commpopadapter(mcontext, mdatas); contentlv.setadapter(adapter); } /** * listview点击事件 * * @param itemclicklistener */ public void setonitemselectedlistener(adapterview.onitemclicklistener itemclicklistener) { if (null != itemclicklistener && null != contentlv) { contentlv.setonitemclicklistener(itemclicklistener); } } }
适配器commpopadapter:
package com.example.junweiliu.filterdemo.adapter; import android.content.context; import android.view.layoutinflater; import android.view.view; import android.view.viewgroup; import android.widget.baseadapter; import android.widget.textview; import com.example.junweiliu.filterdemo.r; import java.util.arraylist; import java.util.list; /** * created by junweiliu on 16/11/7. */ public class commpopadapter extends baseadapter { /** * 筛选条件数据 */ private list<string> mdatas = new arraylist<>(); /** * 布局加载器 */ private layoutinflater minflater; public commpopadapter(context context, list<string> mdatas) { this.mdatas = mdatas; minflater = layoutinflater.from(context); } @override public int getcount() { return mdatas.size(); } @override public object getitem(int i) { return mdatas.get(i); } @override public long getitemid(int i) { return i; } @override public view getview(int i, view convertview, viewgroup viewgroup) { viewholder viewholder = null; if (convertview == null) { viewholder = new viewholder(); convertview = minflater.inflate( r.layout.common_popup_list_item, null); viewholder.mtitletv = (textview) convertview.findviewbyid(r.id.tv_common_listpop_title); convertview.settag(viewholder); } else { viewholder = (viewholder) convertview.gettag(); } viewholder.mtitletv.settext(mdatas.get(i)); return convertview; } /** * vh */ public class viewholder { /** * 筛选项文字tv */ textview mtitletv; } }
相关xml文件:
pop布局文件common_popup_list_dialog:
<?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="wrap_content" android:background="@android:color/transparent" android:gravity="bottom"> <linearlayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@android:color/transparent" android:orientation="vertical"> <view android:layout_width="match_parent" android:layout_height="1dp" android:background="@color/divider_line"/> <listview android:id="@+id/lv_pop" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:divider="@null"/> <view android:layout_width="match_parent" android:layout_height="1dp" android:background="@color/divider_line"/> </linearlayout> </linearlayout>
适配器中的布局common_popup_list_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="wrap_content" android:background="@color/white" android:orientation="vertical" > <relativelayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/white" > <textview android:id="@+id/tv_common_listpop_title" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerhorizontal="true" android:gravity="center" android:padding="15dip" android:text="@string/app_name" /> </relativelayout> <view android:layout_width="match_parent" android:layout_height="0.5dip" android:background="@color/divider_line" android:scaletype="fitxy"/> </linearlayout>
注释很全,也很简单,就不多做解释.
接下来就是调用popwindow,在那调用这个popwinow比较好呢,因为要写一个通用的筛选栏,所以把这些公共的部分都提取出来,放到baseactivity中,需要用到的activity直接继承baseactivity,方便之后使用.
创建一个baseactivity并在其中对popwindow进行处理,代码如下
baseactivity:
package com.example.junweiliu.filterdemo; import android.app.activity; import android.os.bundle; import android.support.annotation.nullable; import android.support.v7.app.appcompatactivity; import android.view.view; import android.view.windowmanager; import android.widget.adapterview; import android.widget.popupwindow; import com.example.junweiliu.filterdemo.pop.commonfilterpop; import java.util.list; /** * created by junweiliu on 16/11/7. */ public class baseactivity extends appcompatactivity { /** * 筛选pop */ private commonfilterpop mpopupwindow; /** * 当前上下文实例 */ protected activity activity; @override protected void oncreate(@nullable bundle savedinstancestate) { super.oncreate(savedinstancestate); this.activity = this; } /** * 列表选择popupwindow * * @param parentview 父view * @param itemtexts 列表项文本集合 * @param itemclicklistener 列表项点击事件 */ public void showfilterpopupwindow(view parentview, list<string> itemtexts, adapterview.onitemclicklistener itemclicklistener, customerdismisslistener dismisslistener) { showfilterpopupwindow(parentview, itemtexts, itemclicklistener, dismisslistener, 0); } /** * 列表选择popupwindow * * @param parentview 父view * @param itemtexts 列表项文本集合 * @param itemclicklistener 列表项点击事件 * @param alpha 背景透明度 */ public void showfilterpopupwindow(view parentview, list<string> itemtexts, adapterview.onitemclicklistener itemclicklistener, customerdismisslistener dismisslistener, float alpha) { // 判断当前是否显示 if (mpopupwindow != null && mpopupwindow.isshowing()) { mpopupwindow.dismiss(); mpopupwindow = null; } mpopupwindow = new commonfilterpop(activity, itemtexts); mpopupwindow.setondismisslistener(dismisslistener); // 绑定筛选点击事件 mpopupwindow.setonitemselectedlistener(itemclicklistener); // 如果透明度设置为0的话,则默认设置为0.6f if (0 == alpha) { alpha = 0.6f; } // 设置背景透明度 windowmanager.layoutparams lp = activity.getwindow().getattributes(); lp.alpha = alpha; activity.getwindow().setattributes(lp); // 显示pop mpopupwindow.showasdropdown(parentview); } /** * 自定义ondismisslistener */ public class customerdismisslistener implements popupwindow.ondismisslistener { @override public void ondismiss() { // 当pop消失的时候,重置背景色透明度 windowmanager.layoutparams lp = activity.getwindow().getattributes(); lp.alpha = 1.0f; activity.getwindow().setattributes(lp); } } /** * 隐藏pop */ public void hidepoplistview() { // 判断当前是否显示,如果显示则dismiss if (mpopupwindow != null && mpopupwindow.isshowing()) { mpopupwindow.dismiss(); mpopupwindow = null; } } }
在baseactivity中对popwindow的显示消失做了处理,在popwindow创建时,改变了背景的透明度,重写了customerdismisslistener来处理popwindow消失时恢复背景透明度.
搞定了popwindow之后,就来结合checkbox来使用吧.使用时应该是这样:
// cb1操作 cb1.setoncheckedchangelistener(new compoundbutton.oncheckedchangelistener() { @override public void oncheckedchanged(compoundbutton compoundbutton, boolean b) { // 将其他的cb设置为未选中,将自己设置为选中 cb1.setchecked(true); cb2.setchecked(false); cb3.setchecked(false); showfilterpopupwindow(showview, showmes1, new adapterview.onitemclicklistener() { @override public void onitemclick(adapterview<?> adapterview, view view, int i, long l) { cb1.settext(showmes1.get(position)); } }, new customerdismisslistener(){ @override public void ondismiss() { super.ondismiss(); // 消失的时候,需要将当前的cb设置为未选中 cb1.setchecked(false); } }); } }); // cb2操作 cb2.setoncheckedchangelistener(new compoundbutton.oncheckedchangelistener() { @override public void oncheckedchanged(compoundbutton compoundbutton, boolean b) { // 将其他的cb设置为未选中,将自己设置为选中 cb2.setchecked(true); cb1.setchecked(false); cb3.setchecked(false); showfilterpopupwindow(showview, showmes2, new adapterview.onitemclicklistener() { @override public void onitemclick(adapterview<?> adapterview, view view, int i, long l) { cb2.settext(showmes1.get(position)); } }, new customerdismisslistener(){ @override public void ondismiss() { super.ondismiss(); // 消失的时候,需要将当前的cb设置为未选中 cb2.setchecked(false); } }); } }); // cb3操作 cb3.setoncheckedchangelistener(new compoundbutton.oncheckedchangelistener() { @override public void oncheckedchanged(compoundbutton compoundbutton, boolean b) { // 将其他的cb设置为未选中,将自己设置为选中 cb3.setchecked(true); cb1.setchecked(false); cb2.setchecked(false); showfilterpopupwindow(showview, showmes3, new adapterview.onitemclicklistener() { @override public void onitemclick(adapterview<?> adapterview, view view, int i, long l) { cb3.settext(showmes3.get(position)); } }, new customerdismisslistener(){ @override public void ondismiss() { super.ondismiss(); // 消失的时候,需要将当前的cb设置为未选中 cb3.setchecked(false); } }); } });
有很多重复的部分,比如在ondismiss方法中,都是将当前cb设置为未选中状态,还有初始化选中状态部分,代码冗余太多,所以来封装一下,在baseactivity当中封装一个方法
/** * tab筛选栏切换 * * @param ischecked 选中状态 * @param showview 展示pop的跟布局 * @param showmes 展示选择的数据 * @param itemclicklistener 点击回调 * @param tabs 所有的cb(需要几个输入几个就可以,cb1,cb2....) */ public void filtertabtoggle(boolean ischecked, view showview, list<string> showmes, adapterview.onitemclicklistener itemclicklistener, final checkbox... tabs) { if (ischecked) { if (tabs.length <= 0) { return; } // 第一个checkbox为当前点击选中的cb,其他cb进行setchecked(false); for (int i = 1; i < tabs.length; i++) { tabs[i].setchecked(false); } showfilterpopupwindow(showview, showmes, itemclicklistener, new customerdismisslistener() { @override public void ondismiss() { super.ondismiss(); // 当pop消失时对第一个cb进行.setchecked(false)操作 tabs[0].setchecked(false); } }); } else { // 关闭checkbox时直接隐藏popuwindow hidepoplistview(); } }
考虑到通用性,用了不定长参数… ,之前用过list,不过用起来不太好用,每次使用的时候,都需要创建list然后去组装一个list,用起来怪麻烦的.这样使用的时候只需要把需要选中的cb放在不定长参数的第一位,其他需要设置未选中的cb放在之后即可.用一下:
// cb操作 cb1.setoncheckedchangelistener(new compoundbutton.oncheckedchangelistener() { @override public void oncheckedchanged(compoundbutton compoundbutton, boolean ischecked) { filtertabtoggle(ischecked, showview, showmes1, new adapterview.onitemclicklistener() { @override public void onitemclick(adapterview<?> adapterview, view view, int position, long l) { hidepoplistview(); cb1.settext(showmes1.get(position)); } }, cb1, cb2, cb3); } });
用起来舒服了很多,可之后又发现了一个比较尴尬的问题.就是需要传入的showmes需要是一个list< string >,有的时候得到的数据并不是一个字符串类型的list,可能是各种类型的list< bean >,这肿么办?解决方法有很多,比如可以这样做:
/** * 展示时间的数据 */ list<timebean> mtimes = new arraylist<>(); /** * 展示的时间str集合 */ list<string> mtimestr = new arraylist<>(); /** * 筛选数据 */ public void formatdata(){ // 初始化时间 timebean timebean1 = new timebean("1天内", "去玩"); timebean timebean2 = new timebean("3天内", "去购物"); timebean timebean3 = new timebean("10天内", "去旅行"); timebean timebean4 = new timebean("30天内", "去赚钱"); mtimes.add(timebean1); mtimes.add(timebean2); mtimes.add(timebean3); mtimes.add(timebean4); // 获取时间中可用于筛选的数据 for (timebean bean : mtimes) { mtimestr.add(bean.gettimestr()); } }
可以从数据源中提取出用到的数据showmes,也不太麻烦,不过有没有更好的办法呢.毕竟每次都从不同的数据源中提取这些数据,也怪费时间的,考虑到这些之后,思来想去,想到一个不错的方法,使用通配符?,首先提出来一个公共接口basefilter,在其中规定一个统一的获取筛选字段的方法,如下:
package com.example.junweiliu.filterdemo.bean; /** * created by junweiliu on 16/11/22. */ public interface basefilter { /** * 获取筛选的 * @return */ public string getfilterstr(); }
然后让需要用到筛选功能的bean实现这个接口中的getfilterstr方法并且去实现它.再对之前的filtertabtoggle方法做一下修改,如下:
bean:
package com.example.junweiliu.filterdemo.bean; /** * created by junweiliu on 16/11/22. */ public class timebean implements basefilter{ /** * 时间str */ string timestr; /** * 时间事件 */ string timeevent; public timebean(string timestr, string timeevent) { this.timestr = timestr; this.timeevent = timeevent; } public string gettimestr() { return timestr; } public void settimestr(string timestr) { this.timestr = timestr; } public string gettimeevent() { return timeevent; } public void settimeevent(string timeevent) { this.timeevent = timeevent; } @override public string getfilterstr() { return timestr; } }
filtertabtogglet方法:
/** * tab筛选栏切换 * * @param ischecked 选中状态 * @param showview 展示pop的跟布局 * @param showmes 展示选择的数据源 * @param itemclicklistener 点击回调 * @param tabs 所有的cb(需要几个输入几个就可以,cb1,cb2....) */ public void filtertabtogglet(boolean ischecked, view showview, list<? extends basefilter> showmes, adapterview.onitemclicklistener itemclicklistener, final checkbox... tabs) { if (ischecked) { if (tabs.length <= 0) { return; } // 第一个checkbox为当前点击选中的cb,其他cb进行setchecked(false); for (int i = 1; i < tabs.length; i++) { tabs[i].setchecked(false); } // 从数据源中提取出展示的筛选条件 list<string> showstr = new arraylist<>(); for (basefilter basefilter : showmes) { showstr.add(basefilter.getfilterstr()); } showfilterpopupwindow(showview, showstr, itemclicklistener, new customerdismisslistener() { @override public void ondismiss() { super.ondismiss(); // 当pop消失时对第一个cb进行.setchecked(false)操作 tabs[0].setchecked(false); } }); } else { // 关闭checkbox时直接隐藏popuwindow hidepoplistview(); } }
这样在使用的时候,直接将list< bean > 类型的数据传进去就可以了.这样整个的通用的筛选栏就实现了.当然根据需求的不同,需要去做修改 ,不过大体的思路及实现就是这样.之后就可以这样用:
// 选择时间cb mtimecb.setoncheckedchangelistener(new compoundbutton.oncheckedchangelistener() { @override public void oncheckedchanged(compoundbutton compoundbutton, boolean ischecked) { filtertabtogglet(ischecked, mtimeall, mtimes, new adapterview.onitemclicklistener() { @override public void onitemclick(adapterview<?> adapterview, view view, int position, long l) { hidepoplistview(); mtimecb.settext(mtimestr.get(position)); } }, mtimecb, mplacecb, mtypecb); } });
最后贴一下完整的mainactivity和baseactivity
mainactivity:
package com.example.junweiliu.filterdemo; import android.os.bundle; import android.view.view; import android.widget.adapterview; import android.widget.checkbox; import android.widget.compoundbutton; import android.widget.linearlayout; import com.example.junweiliu.filterdemo.bean.placebean; import com.example.junweiliu.filterdemo.bean.timebean; import java.util.arraylist; import java.util.list; public class mainactivity extends baseactivity { /** * 展示城市的数据源 */ list<placebean> mpopbeens = new arraylist<>(); /** * 展示类型的数据 */ list<string> mtypes = new arraylist<>(); /** * 展示时间的数据 */ list<timebean> mtimes = new arraylist<>(); /** * 展示的时间str集合 */ list<string> mtimestr = new arraylist<>(); /** * 筛选地区整体 */ linearlayout mplaceall; /** * 筛选城市cb */ checkbox mplacecb; /** * 筛选类型整体 */ linearlayout mtypeall; /** * 筛选类型整体 */ checkbox mtypecb; /** * 筛选时间整体 */ linearlayout mtimeall; /** * 筛选时间整体 */ checkbox mtimecb; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); initdate(); initview(); } /** * 初始化数据 */ private void initdate() { // 初始化城市 placebean placebean1 = new placebean("天津"); placebean placebean2 = new placebean("北京"); placebean placebean3 = new placebean("上海"); placebean placebean4 = new placebean("深圳"); placebean placebean5 = new placebean("四川"); placebean placebean6 = new placebean("杭州"); placebean placebean7 = new placebean("苏州"); mpopbeens.add(placebean1); mpopbeens.add(placebean2); mpopbeens.add(placebean3); mpopbeens.add(placebean4); mpopbeens.add(placebean5); mpopbeens.add(placebean6); mpopbeens.add(placebean7); // 初始化类型 mtypes.add("美食"); mtypes.add("电影"); mtypes.add("化妆品"); mtypes.add("衣服"); mtypes.add("玩具"); mtypes.add("电器"); mtypes.add("装饰"); mtypes.add("超市"); // 初始化时间 timebean timebean1 = new timebean("1天内", "去玩"); timebean timebean2 = new timebean("3天内", "去购物"); timebean timebean3 = new timebean("10天内", "去旅行"); timebean timebean4 = new timebean("30天内", "去赚钱"); mtimes.add(timebean1); mtimes.add(timebean2); mtimes.add(timebean3); mtimes.add(timebean4); // 获取时间中可用于筛选的数据 for (timebean bean : mtimes) { mtimestr.add(bean.gettimestr()); } } /** * 初始化控件 */ private void initview() { mplaceall = (linearlayout) findviewbyid(r.id.ll_place_tab); mplacecb = (checkbox) findviewbyid(r.id.cb_place); mtypeall = (linearlayout) findviewbyid(r.id.ll_type); mtypecb = (checkbox) findviewbyid(r.id.cb_type); mtimeall = (linearlayout) findviewbyid(r.id.ll_time); mtimecb = (checkbox) findviewbyid(r.id.cb_time); // 点击选择城市整体 mplaceall.setonclicklistener(new view.onclicklistener() { @override public void onclick(view view) { if (mplacecb.ischecked()) mplacecb.setchecked(false); else mplacecb.setchecked(true); } }); // 点击选择类型整体 mtypeall.setonclicklistener(new view.onclicklistener() { @override public void onclick(view view) { if (mtypecb.ischecked()) mtypecb.setchecked(false); else mtypecb.setchecked(true); } }); // 点击选择时间整体 mtimeall.setonclicklistener(new view.onclicklistener() { @override public void onclick(view view) { if (mtimecb.ischecked()) mtimecb.setchecked(false); else mtimecb.setchecked(true); } }); // 选择城市cb mplacecb.setoncheckedchangelistener(new compoundbutton.oncheckedchangelistener() { @override public void oncheckedchanged(compoundbutton compoundbutton, boolean ischecked) { filtertabtogglet(ischecked, mplaceall, mpopbeens, new adapterview.onitemclicklistener() { @override public void onitemclick(adapterview<?> adapterview, view view, int position, long l) { hidepoplistview(); mplacecb.settext(mpopbeens.get(position).getfilterstr()); } }, mplacecb, mtypecb, mtimecb); } }); // 选择类型cb mtypecb.setoncheckedchangelistener(new compoundbutton.oncheckedchangelistener() { @override public void oncheckedchanged(compoundbutton compoundbutton, boolean ischecked) { filtertabtoggle(ischecked, mtypeall, mtypes, new adapterview.onitemclicklistener() { @override public void onitemclick(adapterview<?> adapterview, view view, int position, long l) { hidepoplistview(); mtypecb.settext(mtypes.get(position)); } }, mtypecb, mplacecb, mtimecb); } }); // 选择时间cb mtimecb.setoncheckedchangelistener(new compoundbutton.oncheckedchangelistener() { @override public void oncheckedchanged(compoundbutton compoundbutton, boolean ischecked) { filtertabtoggle(ischecked, mtimeall, mtimestr, new adapterview.onitemclicklistener() { @override public void onitemclick(adapterview<?> adapterview, view view, int position, long l) { hidepoplistview(); mtimecb.settext(mtimestr.get(position)); } }, mtimecb, mplacecb, mtypecb); } }); } }
baseactivity:
package com.example.junweiliu.filterdemo; import android.app.activity; import android.os.bundle; import android.support.annotation.nullable; import android.support.v7.app.appcompatactivity; import android.view.view; import android.view.windowmanager; import android.widget.adapterview; import android.widget.checkbox; import android.widget.popupwindow; import com.example.junweiliu.filterdemo.bean.basefilter; import com.example.junweiliu.filterdemo.pop.commonfilterpop; import java.util.arraylist; import java.util.list; /** * created by junweiliu on 16/11/7. */ public class baseactivity extends appcompatactivity { /** * 筛选pop */ private commonfilterpop mpopupwindow; /** * 当前上下文实例 */ protected activity activity; @override protected void oncreate(@nullable bundle savedinstancestate) { super.oncreate(savedinstancestate); this.activity = this; } /** * 列表选择popupwindow * * @param parentview 父view * @param itemtexts 列表项文本集合 * @param itemclicklistener 列表项点击事件 */ public void showfilterpopupwindow(view parentview, list<string> itemtexts, adapterview.onitemclicklistener itemclicklistener, customerdismisslistener dismisslistener) { showfilterpopupwindow(parentview, itemtexts, itemclicklistener, dismisslistener, 0); } /** * 列表选择popupwindow * * @param parentview 父view * @param itemtexts 列表项文本集合 * @param itemclicklistener 列表项点击事件 */ public void showfilterpopupwindow(view parentview, list<string> itemtexts, adapterview.onitemclicklistener itemclicklistener, customerdismisslistener dismisslistener, float alpha) { // 判断当前是否显示 if (mpopupwindow != null && mpopupwindow.isshowing()) { mpopupwindow.dismiss(); mpopupwindow = null; } mpopupwindow = new commonfilterpop(activity, itemtexts); mpopupwindow.setondismisslistener(dismisslistener); // 绑定筛选点击事件 mpopupwindow.setonitemselectedlistener(itemclicklistener); // 如果透明度设置为0的话,则默认设置为0.6f if (0 == alpha) { alpha = 0.6f; } // 设置背景透明度 windowmanager.layoutparams lp = activity.getwindow().getattributes(); lp.alpha = alpha; activity.getwindow().setattributes(lp); // 显示pop mpopupwindow.showasdropdown(parentview); } /** * tab筛选栏切换 * * @param ischecked 选中状态 * @param showview 展示pop的跟布局 * @param showmes 展示选择的数据 * @param itemclicklistener 点击回调 * @param tabs 所有的cb(需要几个输入几个就可以,cb1,cb2....) */ public void filtertabtoggle(boolean ischecked, view showview, list<string> showmes, adapterview.onitemclicklistener itemclicklistener, final checkbox... tabs) { if (ischecked) { if (tabs.length <= 0) { return; } // 第一个checkbox为当前点击选中的cb,其他cb进行setchecked(false); for (int i = 1; i < tabs.length; i++) { tabs[i].setchecked(false); } showfilterpopupwindow(showview, showmes, itemclicklistener, new customerdismisslistener() { @override public void ondismiss() { super.ondismiss(); // 当pop消失时对第一个cb进行.setchecked(false)操作 tabs[0].setchecked(false); } }); } else { // 关闭checkbox时直接隐藏popuwindow hidepoplistview(); } } /** * tab筛选栏切换 * * @param ischecked 选中状态 * @param showview 展示pop的跟布局 * @param showmes 展示选择的数据源 * @param itemclicklistener 点击回调 * @param tabs 所有的cb(需要几个输入几个就可以,cb1,cb2....) */ public void filtertabtogglet(boolean ischecked, view showview, list<? extends basefilter> showmes, adapterview.onitemclicklistener itemclicklistener, final checkbox... tabs) { if (ischecked) { if (tabs.length <= 0) { return; } // 第一个checkbox为当前点击选中的cb,其他cb进行setchecked(false); for (int i = 1; i < tabs.length; i++) { tabs[i].setchecked(false); } // 从数据源中提取出展示的筛选条件 list<string> showstr = new arraylist<>(); for (basefilter basefilter : showmes) { showstr.add(basefilter.getfilterstr()); } showfilterpopupwindow(showview, showstr, itemclicklistener, new customerdismisslistener() { @override public void ondismiss() { super.ondismiss(); // 当pop消失时对第一个cb进行.setchecked(false)操作 tabs[0].setchecked(false); } }); } else { // 关闭checkbox时直接隐藏popuwindow hidepoplistview(); } } /** * 自定义ondismisslistener */ public class customerdismisslistener implements popupwindow.ondismisslistener { @override public void ondismiss() { // 当pop消失的时候,重置背景色透明度 windowmanager.layoutparams lp = activity.getwindow().getattributes(); lp.alpha = 1.0f; activity.getwindow().setattributes(lp); } } /** * 隐藏pop */ public void hidepoplistview() { // 判断当前是否显示,如果显示则dismiss if (mpopupwindow != null && mpopupwindow.isshowing()) { mpopupwindow.dismiss(); mpopupwindow = null; } } }
源码地址:android通用的筛选栏源码
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: 世界新七大奇迹 北京大兴机场与港珠澳大桥都已正式运营
下一篇: Unity相机移动之屏幕边缘检测