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

前言:前几天用58同城APP找房子的时候,看到筛选下拉框蛮不错的,然后也有很多朋友需要实现这个功能,于是从网上下载了一个demo,在他的基础上进行修改,花了几个小时对他的代码进行修改,重构,封装.把一些公共的东西抽取出来,选择下拉框那块做成一个工具类,然后通过接口回调回来.

效果图如下:

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


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   欢迎大家的加入


 

点击下载源码

上一篇:带你实现开发者头条APP(三) 首页实现


下一篇:Android接入百度自动更新SDK