• 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

  • 相关阅读:
    [Go] 理解(*interface{})(nil) 赋值的变量是否为nil
    [Linux] 理解CPU缓存的伪共享问题
    [MySQL] 理解InnoDB并发高的原因
    [Go] 理解计算机负数的表示以及整数范围
    [Go]理解golang项目性能分析工具trace
    [Go]理解golang项目性能分析工具PProf
    [Go] 理解切片slice扩容
    [javascript]解决多个版本的jquery库或者$冲突
    [Linux] 理解Reactor 模型
    [Linux] 理解I/O多路复用
  • 原文地址:https://www.cnblogs.com/likeju/p/4834879.html
Copyright © 2020-2023  润新知