最近在做一个社交类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. Excel多表头设置二级联动选择

    1.初始准备 2.全选,然后开始 -> 查找和选择 -> 定位条件 3.公式 -> 根据所选内容创建 因为一级联动数据在第一行,所以选首行 4.因为学校信息与联动数据不在同一个she ...

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

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

  6. Android PopupWindow的使用和分析

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

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

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

  8. android 仿微信朋友圈图片选择控件

    调用方式(布局文件就是一个自定义控件): private ArrayList<String> selectedImages; @BindView(R.id.imagePicker) Ima ...

  9. Chosen 的 optgroup 第一级单击的时候选择二级的全部

    相关环境 及 版本 Chosen (v1.6.2) https://harvesthq.github.io/chosen/ jQuery (v1.8.3) 官网 http://jquery.com/ ...

随机推荐

  1. 新浪微博OAuth2.0的用法

    最近学习Android开发,照着视频开发新浪微博,但是视频里的介绍的是OAuth1.0的授权方式,试了半天发现用不了. 原来现在一般没审核的用户只能使用OAuth2.0了,视频教学里的方法已经过时了. ...

  2. ServiceStack 介绍

    关于ServiceStack ServiceStack 官网介绍: Opensource .NET and Mono REST Web Services framework 什么是 ServiceSt ...

  3. position 属性和 z-index 属性对页面节点层级影响的例子

    转:http://www.neoease.com/tutorials/z-index/ 不设 z-index 属性 单层节点 双层节点 多层节点

  4. DDD:《实现领域驱动》拾贝(待续)

    Design is not just what it looks like and feels like. Design is how it works.

  5. 《微信小程序七日谈》- 第三天:玩转Page组件的生命周期

    <微信小程序七日谈>系列文章: 第一天:人生若只如初见: 第二天:你可能要抛弃原来的响应式开发思维: 第三天:玩转Page组件的生命周期: 第四天:页面路径最多五层?导航可以这么玩 前两篇 ...

  6. IEE分月表改造

    IEE版本:5.1.40 需求:由于目前的IEE版本并不支持分区表,且删除历史数据效率很低,删除部分数据后空间释放方面也不理想. 现采用按月分表存放数据.这样卸载历史数据时,直接删除历史表即可. 改造 ...

  7. Oracle 11g 安全加固

    1.安全加固的检查方向 2.安全加固检查safeCheck.sh 3.安全加固执行safeExec.sh 1.安全加固的检查方向 1.1.sysdba用户远程登录限制(查看Oracle登录认证方式) ...

  8. "浅谈Android"第一篇:Android系统简介

    近来,看了一本书,名字叫做<第一行代码>,是CSDN一名博主写的,一本Android入门级的书,比较适合新手.看了书之后,有感而发,想来进行Android开发已经有一年多了,但欠缺系统化的 ...

  9. Dell_r720服务器部署

    没错,就是它-->                             前言:本来是写在word文档上作为笔记的,想想觉得不能浪费我在机房被狂虐两天总结出来的这点小经验, 还是分享一下吧,说 ...

  10. thread_CyclicBarrier回环栅栏

    CyclicBarrier回环栅栏,字面意思是可循环使用(Cyclic)的屏障(Barrier).通过它可以实现让一组线程等待至某个状态之后再全部同时执行. 它要做的事情是,让一组线程到达一个屏障(也 ...