前言:前几天用58同城APP找房子的时候,看到筛选下拉框蛮不错的,然后也有很多朋友需要实现这个功能,于是从网上下载了一个demo,在他的基础上进行修改,花了几个小时对他的代码进行修改,重构,封装.把一些公共的东西抽取出来,选择下拉框那块做成一个工具类,然后通过接口回调回来.
效果图如下:
1.MainActivity.java 用户点击区域TextView的时候,初始化自定义控件PopupWindow,然后显示PopupWindow.通过PopupWindow构造参数传入一个选择完成的监听接口实现。
/** * 主Activity * @author ansen * @create time 2015-09-25 */ public class MainActivity extends Activity implements OnClickListener{ private SelectPopupWindow mPopupWindow = null; private TextView tvZuQuyu; private String[] parentStrings = {"全城","中原区","二七区","管城区","金水区","上街区","惠济区","郑东新区","高新区","经开区","郑州周边"}; private String[][] childrenStrings={{}, {"中原1","中原2","中原3","中原4","中原5","中原6","中原7","中原8","中原9","中原10","中原11","中原12","中原13","中原14","中原15"}, {"二七1","二七2","二七3","二七4","二七5","二七6","二七7","二七8","二七9","二七10","二七11","二七12","二七13","二七14","二七15"}, {"管城1","管城2","管城3","管城4","管城5","管城6","管城7","管城8","管城9","管城10","管城11","管城12","管城13","管城14","管城15"}, {"金水1","金水2","金水3","金水4","金水5","金水6","金水7","金水8","金水9","金水10","金水11","金水12","金水13","金水14","金水15"}, {"上街1","上街2","上街3","上街4","上街5","中原6","中原7","中原8","中原9","中原10","中原11","中原12","中原13","中原14","中原15"}, {"中原1","中原2","中原3","中原4","中原5","中原6","中原7","中原8","中原9","中原10","中原11","中原12","中原13","中原14","中原15"}, {"郑东新区1","郑东新区2","郑东新区3","中原4","中原5","中原6","中原7","中原8","中原9","中原10","中原11","中原12","中原13","中原14","中原15"}, {"高新区1","高新区2","高新区3","中原4","中原5","中原6","中原7","中原8","中原9","中原10","中原11","中原12","中原13","中原14","中原15"}, {"经开区1","经开区2","经开区3","中原4","中原5","中原6","中原7","中原8","中原9","中原10","中原11","中原12","中原13","中原14","中原15"}, {"周边1","周边2","周边3","中原4","中原5","中原6","中原7","中原8","中原9","中原10","中原11","中原12","中原13","中原14","中原15"}, }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_chuzu_city_main); tvZuQuyu = (TextView) findViewById(R.id.tvZuQuyu); tvZuQuyu.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.tvZuQuyu: if(mPopupWindow == null){ mPopupWindow = new SelectPopupWindow(parentStrings,childrenStrings,this,selectCategory); } mPopupWindow.showAsDropDown(tvZuQuyu, -5, 10); break; } } /** * 选择完成回调接口 */ private SelectCategory selectCategory=new SelectCategory() { @Override public void selectCategory(int parentSelectposition,int childrenSelectposition) { String parentStr=parentStrings[parentSelectposition]; String childrenStr=childrenStrings[parentSelectposition][childrenSelectposition]; Toast.makeText(MainActivity.this, "父类别:"+parentStr+" 子类别:"+childrenStr, 0).show(); } }; }
2.SelectPopupWindow.java 自定义的PopupWindow,在构造方法中设置内容,设置背景等.给要显示的两个ListView设置适配器,添加ListView点击事件,点击子类别的时候回调选中的两个下标,关闭PopupWindow。
/** * 选择PopupWindow * @author ansen * @create time 2015-10-09 */ public class SelectPopupWindow extends PopupWindow{ private SelectCategory selectCategory; private String[] parentStrings; private String[][] childrenStrings; private ListView lvParentCategory = null; private ListView lvChildrenCategory= null; private ParentCategoryAdapter parentCategoryAdapter = null; private ChildrenCategoryAdapter childrenCategoryAdapter = null; /** * @param parentStrings 字类别数据 * @param childrenStrings 字类别二位数组 * @param activity * @param selectCategory 回调接口注入 */ public SelectPopupWindow(String[] parentStrings,String[][] childrenStrings,Activity activity,SelectCategory selectCategory) { this.selectCategory=selectCategory; this.parentStrings=parentStrings; this.childrenStrings=childrenStrings; View contentView = LayoutInflater.from(activity).inflate(R.layout.layout_quyu_choose_view, null); DisplayMetrics dm = new DisplayMetrics(); activity.getWindowManager().getDefaultDisplay().getMetrics(dm); // 获取手机屏幕的大小 this.setContentView(contentView); this.setWidth(dm.widthPixels); this.setHeight(dm.heightPixels*7/10); /* 设置背景显示 */ setBackgroundDrawable(activity.getResources().getDrawable(R.drawable.pop_bg)); /* 设置触摸外面时消失 */ setOutsideTouchable(true); setTouchable(true); setFocusable(true); /*设置点击menu以外其他地方以及返回键退出 */ /** * 1.解决再次点击MENU键无反应问题 */ contentView.setFocusableInTouchMode(true); //父类别适配器 lvParentCategory= (ListView) contentView.findViewById(R.id.lv_parent_category); parentCategoryAdapter = new ParentCategoryAdapter(activity,parentStrings); lvParentCategory.setAdapter(parentCategoryAdapter); //子类别适配器 lvChildrenCategory= (ListView) contentView.findViewById(R.id.lv_children_category); childrenCategoryAdapter = new ChildrenCategoryAdapter(activity); lvChildrenCategory.setAdapter(childrenCategoryAdapter); lvParentCategory.setOnItemClickListener(parentItemClickListener); lvChildrenCategory.setOnItemClickListener(childrenItemClickListener); } /** * 子类别点击事件 */ private OnItemClickListener childrenItemClickListener=new OnItemClickListener(){ @Override public void onItemClick(AdapterView<?> parent, View view, int position,long id) { if(selectCategory!=null){ selectCategory.selectCategory(parentCategoryAdapter.getPos(),position); } dismiss(); } }; /** * 父类别点击事件 */ private OnItemClickListener parentItemClickListener=new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position,long id) { childrenCategoryAdapter.setDatas(childrenStrings[position]); childrenCategoryAdapter.notifyDataSetChanged(); parentCategoryAdapter.setSelectedPosition(position); parentCategoryAdapter.notifyDataSetChanged(); } }; /** * 选择成功回调 * @author apple * */ public interface SelectCategory{ /** * 把选中的下标通过方法回调回来 * @param parentSelectposition 父类别选中下标 * @param childrenSelectposition 子类别选中下标 */ public void selectCategory(int parentSelectposition,int childrenSelectposition); } }
3.layout_quyu_choose_view.xml PopupWindow展示的布局文件,两个就两个ListView
<?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:background="@drawable/pop_bg" android:orientation="horizontal"> <ListView android:id="@+id/lv_parent_category" android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="3" android:background="@color/zu_choose_left_item_bg" android:cacheColorHint="@android:color/transparent" android:divider="@color/zu_choose_left_item_diveder" android:dividerHeight="1dp" android:scrollbars="none"/> <View android:layout_width="1dp" android:layout_height="fill_parent" android:background="@color/zu_choose_left_item_diveder"/> <ListView android:id="@+id/lv_children_category" android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="4" android:background="@color/zu_choose_right_item_bg" android:cacheColorHint="@android:color/transparent" android:divider="@color/zu_choose_left_item_diveder" android:dividerHeight="1dp" android:scrollbars="none" /> </LinearLayout>
4.ParentCategoryAdapter.java 父类别适配器的实现,跟我们平时经常写的适配器没啥两样,就在getView方法里面判断是否选中,选中的那个下标颜色设置的不一样.
/** * 父类别 适配器 * @author ansen * @create time 2015-09-25 */ public class ParentCategoryAdapter extends BaseAdapter { private Context mContext; private String[] str; private int pos; public ParentCategoryAdapter(Context context,String[] str) { mContext = context; this.str = str; } @Override public int getCount() { return str.length; } @Override public Object getItem(int position) { return null; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if (convertView == null) { holder = new ViewHolder(); convertView = LayoutInflater.from(mContext).inflate(R.layout.activity_parent_category_item, null); holder.tvParentCategoryName = (TextView) convertView.findViewById(R.id.tv_parent_category_name); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.tvParentCategoryName.setText(str[position]); if(pos==position){ holder.tvParentCategoryName.setTextColor(mContext.getResources().getColor(R.color.list_text_select_color)); convertView.setBackgroundColor(mContext.getResources().getColor(R.color.zu_choose_right_item_bg)); }else{ holder.tvParentCategoryName.setTextColor(mContext.getResources().getColor(android.R.color.black)); convertView.setBackgroundColor(mContext.getResources().getColor(R.color.zu_choose_left_item_bg)); } return convertView; } private class ViewHolder { private TextView tvParentCategoryName; } public void setSelectedPosition(int pos) { this.pos = pos; } public int getPos() { return pos; } }
还有子类别适配器,一些布局文件我就不全部贴出来了,有需要的可以下载源码.
推荐下自己创建的android QQ群:202928390 欢迎大家的加入