当前位置: 代码迷 >> Android >> Android PopupWindow使用之地区、学校抉择二级联动
  详细解决方案

Android PopupWindow使用之地区、学校抉择二级联动

热度:74   发布时间:2016-04-27 22:55:23.0
Android PopupWindow使用之地区、学校选择二级联动

  最近在做一个社交类APP时,希望用户在注册时根据地区来选择自己所在的学校,由于用户手动输入学校,可能会出现各种问题,不利于后面对用户信息的统计。于是决定在客户端做好设置,用户只要根据地区来选择就好。第一想法就是使用PopupWindow,用弹框的方式让用户来选择。让实现的效果如下:

下面就来讲一下是如何实现的(数据是从网络获取的,JSON解析使用的是Gson,网络库用的是Volley)

工程结构:

1、创建一个布局文件:view_select_province_list.xml,主要包括一个TextView(用来显示标题)和两个ListView(默认显示地区ListView,隐藏SchoolListView)

<?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="vertical"    >    <TextView        android:id="@+id/list_title"        android:layout_width="match_parent"        android:layout_height="50dp"        android:background="#3b3b3b"        android:gravity="center"        android:text="选择地区"        android:textColor="#ffffff"        android:textSize="16sp"/>    <ListView        android:id="@+id/province"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_gravity="center"        android:background="#e4e4e4"        android:divider="#aeaeae"        android:dividerHeight="1dp"></ListView>    <ListView        android:id="@+id/school"        android:visibility="gone"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_gravity="center"        android:background="#e4e4e4"        android:divider="#aeaeae"        android:dividerHeight="1dp"></ListView></LinearLayout>

2、初始化PopupWindow

private void initPopView() {        parent = this.getWindow().getDecorView();        View popView = View.inflate(this, R.layout.view_select_province_list, null);        mTitle = (TextView) popView.findViewById(R.id.list_title);        mProvinceListView = (ListView) popView.findViewById(R.id.province);        mSchoolListView = (ListView) popView.findViewById(R.id.school);        mProvinceListView.setOnItemClickListener(itemListener);        mSchoolListView.setOnItemClickListener(itemListener);        mProvinceAdapter = new ProvinceAdapter(this);        mProvinceListView.setAdapter(mProvinceAdapter);        mSchoolAdapter = new SchoolAdapter(this);        mSchoolListView.setAdapter(mSchoolAdapter);        int width = getResources().getDisplayMetrics().widthPixels * 3 / 4;        int height = getResources().getDisplayMetrics().heightPixels * 3 / 5;        mPopWindow = new PopupWindow(popView, width, height);        ColorDrawable dw = new ColorDrawable(0x30000000);        mPopWindow.setBackgroundDrawable(dw);        mPopWindow.setFocusable(true);        mPopWindow.setTouchable(true);        mPopWindow.setOutsideTouchable(true);//允许在外侧点击取消        loadProvince();        mPopWindow.setOnDismissListener(listener);    }

其中,要想使PopupWindow点击空白区域取消,必须设置

ColorDrawable dw = new ColorDrawable(0x30000000);

mPopWindow.setBackgroundDrawable(dw);

mPopWindow.setOutsideTouchable(true);

3、显示PopupWindow

private void showPopWindow() 
{ mPopWindow.showAtLocation(parent, Gravity.CENTER, 0, 0);}

4、下载地区和学校数据(这里用的是volley和gson解析数据)

private void loadProvince() {        mRequestQueue = Volley.newRequestQueue(this);        GsonRequest<Province> request = new GsonRequest<Province>(Request.Method.POST, Config.PROVINCE_URL,                Province.class, new Response.Listener<Province>() {            @Override            public void onResponse(Province response) {                if (response.getData() != null && response.getError_code() == 0) {                    mProvinceAdapter.setList(response.getData());                    mProvinceAdapter.notifyDataSetChanged();                }            }        }, new Response.ErrorListener() {            @Override            public void onErrorResponse(VolleyError volleyError) {            }        }, this);        mRequestQueue.add(request);    }    private void loadSchool() {        mRequestQueue = Volley.newRequestQueue(this);        GsonRequest<School> request = new GsonRequest<>(Request.Method.POST, Config.SCHOOL_URL + provinceId, School.class,                new Response.Listener<School>() {                    @Override                    public void onResponse(School response) {                        if (response.getData() != null && response.getError_code() == 0){                            mSchoolAdapter.setList(response.getData());                            mSchoolAdapter.notifyDataSetChanged();                        }                    }                }, new Response.ErrorListener() {            @Override            public void onErrorResponse(VolleyError volleyError) {            }        }, this);        mRequestQueue.add(request);    }

5、设置ListView 的Item点击事件

/**     * ListView Item点击事件     */    AdapterView.OnItemClickListener itemListener = new AdapterView.OnItemClickListener() {        @Override        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {            if (parent == mProvinceListView) {                ProvinceList provinceName = (ProvinceList) mProvinceListView.getItemAtPosition(position);                provinceId = provinceName.getProvince_id();                mTitle.setText("选择学校");                mProvinceListView.setVisibility(View.GONE);//隐藏地区                mSchoolListView.setVisibility(View.VISIBLE);//显示学校                loadSchool();            } else if (parent == mSchoolListView) {                SchoolList schoolName = (SchoolList) mSchoolListView.getItemAtPosition(position);                mSelectSchool.setText(schoolName.getSchool_name());                mPopWindow.dismiss();            }        }    };

6、PopupWindow设置OnDismissListener,目的是为了再次进入选择的时候,直接进入学校而不是地区的选择

/**     * popWindow消失监听事件     */    PopupWindow.OnDismissListener listener = new PopupWindow.OnDismissListener() {        @Override        public void onDismiss() {            mTitle.setText("选择地区");            mProvinceListView.setVisibility(View.VISIBLE);//显示地区            mSchoolAdapter.setList(new ArrayList<SchoolList>());//设置一个空的List,避免再次选择学校后弹出的还是刚才的地区对应的学校            mSchoolAdapter.notifyDataSetChanged();            mSchoolListView.setVisibility(View.GONE);//隐藏学校        }    };

7、好了,这样一个基于PopupWindow的二级联动弹框选择就完成了,其中,还有ListView的Adapter在这里我就没有贴出来了,写法和我们平常用的适配器一样。我已经把代码开源到我的GitHub上了,有需要的可以下载看看。

GitHub地址:https://github.com/tonycheng93/PopWindow

 

 

 

  相关解决方案