最近在做一个社交类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

 

Android PopupWindow使用之地区、学校选择二级联动的更多相关文章

  1. 7.Android开源项目WheelView的时间和地址联动选择对话框

    类似WheelView的时间和地址联动选择对话框在现在App经常看到,今天小结下. 主布局界面: <LinearLayout xmlns:android="http://schemas ...

  2. android中利用实现二级联动的效果

    按照惯例,首先上一张效果图. 本篇文章实现的效果就是如图中所圈的那样,实现类似于HTML中的二级联动的效果. 对于第一个选项我们读取的是本地xml文件来填充数据的, 对于第二个选项我们读取的是通过中央 ...

  3. Android之单复选框及Spinner实现二级联动

    一.基础学习 1.图形学真的很神奇啊....查了些资料做出了3D云标签,哈哈...其实直接拿来用的,我们要效仿鲁迅先生的拿来主义,嘿嘿~~3D标签云就是做一个球面,然后再球面上取均匀分布的点,把点坐标 ...

  4. Android PopupWindow Dialog 关于 is your activity running 崩溃详解

    Android PopupWindow Dialog 关于 is your activity running 崩溃详解 [TOC] 起因 对于 PopupWindow Dialog 需要 Activi ...

  5. Android PopupWindow的使用和分析

    Android PopupWindow的使用和分析 PopupWindow使用 PopupWindow这个类用来实现一个弹出框,可以使用任意布局的View作为其内容,这个弹出框是悬浮在当前activi ...

  6. Android PopupWindow的使用技巧(转)

    Android PopupWindow的使用技巧 PopupWindow是Android上自定义弹出窗口,使用起来很方便. PopupWindow的构造函数为 public PopupWindow(V ...

  7. asp.net 使用DroDownList来实现二级联动

    今天做新闻发布系统的时候,用到了二级联动,我把使用方法记录下来,以便日后查阅以及帮助新手朋友们.下面是效果图: 下面来讲解一下实现的方法: 1.在.aspx页面中,拖入两个DroDownList控件. ...

  8. 利用JavaScript来实现省份—市县的二级联动

    所谓省-市二级联动是指当选择省份下拉选择框时,市县的下拉框会根据选择的省市而有相应的市县加载出来,如下图所示选择"上海市",城市的下拉选择框只会出现上海的市县: 这种二级联动非常常 ...

  9. 原生js二级联动

    今天说的这个是原生js的二级联动,在空白页面里动态添加并作出相对应的效果. 1 //创建两个下拉列表 select标签 是下拉列表 var sel = document.createElement(& ...

随机推荐

  1. HTTP Method 之 Post VS. Get

    引言 WebAPI 现在非常火的轻量服务框架,因其使用得使用了Http协议,并且具备了可协商内容(生成不同内容格式)等优势,所以在互联网业务中被广泛使用. 那作为HTTP最常用的两个方法Get和Pos ...

  2. UML大战需求分析——阅读笔记06

    状态机图和活动图在样子比较相似,但状态机图是用来为对象的状态及造成状态改变的事件建模.我们大二学习UML统一建模语言状态机图模块时了解到,UML的状态机图主要用于建立对象类或对象的动态行为模型,描述系 ...

  3. 关于js单线程(转载)

    进程和线程都是操作系统的概念.进程是应用程序的执行实例,每一个进程都是由私有的虚拟地址空间.代码.数据和其它系统资源所组成:进程在运行过程中能够申请创建和使用系统资源(如独立的内存区域等),这些资源也 ...

  4. 第 31 章 项目实战-PC 端固定布局[3]

    学习要点: 1.搜索区 2.插入大图 3.搜索框 主讲教师:李炎恢 本章主要开始使用学习用 HTML5 和 CSS3 来构建 Web 页面,第一个项目采用 PC 端固定布局来实现. 一.搜索区 本节课 ...

  5. Git私钥openssh格式转ppk

    已有my.openssh私钥文件,以及Key passphrase:4c264a73544ee7f3bc6ba6f8a416b6efec9d7cc6e71b745c479159cc7ee0a8cb 若 ...

  6. 【Win10 UWP】微信SDK基本使用方法和基本原理

    上回讲到,作为一个长期散播温暖,散播希望的小清新无公害WP开发者,继QQ SDK之后,又把UWP微信SDK这茬了结了,仅供学习交流. 1.安装微信SDK for UWP 微信官方此前明确说明短时间内暂 ...

  7. POJ 3281:Dining(最大流)

    http://poj.org/problem?id=3281 题意:有n头牛,f种食物,d种饮料,每头牛有fnum种喜欢的食物,dnum种喜欢的饮料,每种食物如果给一头牛吃了,那么另一个牛就不能吃这种 ...

  8. iOS出现&lt;object returned empty description&gt;的解决方法

    iOS出现<object returned empty description>的解决方法: 使用  [str length] <= 0  判断处理

  9. 会员制实现C2B定制有机农产品,被中粮我买投资的良食网这样卖有机生鲜

    前几天,中粮我买网战略投资了位于深圳的有机生鲜自营平台良食网,宣布双方将会在供应链上展开合作.然而良食网对大家来说还是比较陌生的,为此36氪专访了良食网的创始人唐忠. 良食网成立于2011年,是一家以 ...

  10. expect实现交互式脚本

    #!/usr/bin/expect -f ##告诉解释器用expect来解释 set timeout 6 ##设置超时时间 ] ## 这个是传递给脚本的第一个参数,并把参数赋值给user ] ## 这 ...