android模仿58筛选下拉框(PopupWindow实现)

前言:前几天用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   欢迎大家的加入


 

点击下载源码

时间: 2024-09-17 16:47:05

android模仿58筛选下拉框(PopupWindow实现)的相关文章

Android下拉框PopupWindow使用详解

本文实例为大家分享了Android下拉框PopupWindow展示的具体代码,供大家参考,具体内容如下 activity_main.xml布局 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_paren

模仿google搜索下拉框

提示:您可以先修改部分代码再运行 (eg. ShanDong) 模仿google搜索下拉框,免费空间,免费asp空间,免费域注册 提示:您可以先修改部分代码再运行

Android UI自定义Spinner下拉框(用popuwindow实现)

Android提供的Spinner可能会因为项目的需求而不能使用,这时候我们往往会自己定义一个.最近在做的项目遇到了这种情况,自己用PopuWindow定义了一个下拉框的样式,记录下来留着以后参考~先上效果图~ 点击头部右边的按钮,弹出长度与上方的控件长度一致的下拉框. 下面来说说是如何实现的.定义出第一个图片的布局和弹出框(一个listView)的布局,程序的源码里面有,这里就不在多说了~ListView需要自己定义一个MyspinnerAdapter~做好这些准备之后,就是弹出框的实现了~

android用PopWindow做下拉框实例代码

最近在做下拉框,本来想用spinner,可是spinner达不到项目要求,跟同学同事问了一圈,都在用popwindow,网上看了一下,popwindow挺简单的,可定制性挺强的,符合我的要求,所以,借鉴网上看的代码,自己撸了一遍.写篇博客以防忘记. 首先,先写个自定义布局,代码如下 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://sche

Android实现三级联动下拉框 下拉列表spinner

 主要实现办法:动态加载各级下拉值的适配器 在监听本级下拉框,当本级下拉框的选中值改变时,随之修改下级的适配器的绑定值                  XML布局: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="m

Android实现三级联动下拉框 下拉列表spinner的实例代码_Android

主要实现办法:动态加载各级下拉值的适配器 在监听本级下拉框,当本级下拉框的选中值改变时,随之修改下级的适配器的绑定值 列表spinner的实例代码_Android-spinner下拉框样式">             XML布局: 复制代码 代码如下: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schema

Android实现三级联动下拉框 下拉列表spinner的实例代码

主要实现办法:动态加载各级下拉值的适配器 在监听本级下拉框,当本级下拉框的选中值改变时,随之修改下级的适配器的绑定值 XML布局: 复制代码 代码如下:<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="mat

android中自定义下拉框

android自带的下拉框好用不?我觉得有时候好用,有时候难有,项目规定这样的效果,自带的控件实现不了,那么只有我们自己来老老实实滴写一个新的了,其实最基本的下拉框就像一些资料填写时,点击的时候出现在编辑框的下面,然后又很多选项的下拉框,可是我在网上找了一下,没有这种下拉框额,就自己写了一个,看效果图先: ,这个是资料填写的一部分界面,三个下拉框,选择故乡所在地: 点击之后弹出下拉框,选择下面的选项: 三个下拉框时关联的,第一个决定了第二数据内容,第二个决定了第三个数据内容,如果三个全部选好之后

Android第三方开源下拉框NiceSpinner使用详解

android原生的下拉框Spinner基本上可以满足Android开发对于下拉选项的设计需求,但现在越来越流行的下拉框不满足于Android原生提供的下拉框Spinner所提供的设计样式,而改用自定制或者第三方设计的下拉框Spinner. NiceSpinner是一个第三方开源的下拉框Spinner,其在github上的项目主页是:https://github.com/arcadefire/nice-spinner  NiceSpinner原设计效果如动图所示: 但是通常开发者对于可能还需要对