声明:本文内容思路到实现都是本人完成,如有雷同纯属巧合,省市字符串数组内容是借用了别人的(具体是谁的没记下来,搜的时候看到实现效果不太一样,就借用了这一部分,在这里表示感谢和抱歉),转载本文请注明出处。
之前搜别人的好多都没有这样效果,所以就自己写了一个,一开始想到这样写的时候,还不确定能不能达到效果,刚写出来简单模型的时候发现效果挺接近的,就慢慢改成了这样,效果感觉挺好的。
有些布局控件和变量命名很随意,不要见怪。
个人觉得这个二级联动实现比较简单,但是有局限性,第一级菜单选项很多的话会比较麻烦,实现省市县三级菜单的话就更不可行了。
其实本文主要是实现Dialog省市二级联动菜单,listview数据的处理并不是很好,可以使用更高效的数据加载方式,不用像我这样把数据弄的这么麻烦。特别是switch case获取城市的数组数据,太麻烦了!
几个背景图形 ↓ (颜色形状可以自行设置)
放在drawable文件夹下
数组最后都加了一个空数据,是为了让本来最后一个数据可以显示在中间位置
- -省份-
- 北京
- 天津
- 河北
- 山西
- 内蒙古
- 辽宁
- 吉林
- 黑龙江
- 上海
- 江苏
- 浙江
- 安徽
- 福建
- 江西
- 山东
- 河南
- 湖北
- 湖南
- 广东
- 广西
- 海南
- 重庆
- 四川
- 贵州
- 云南
- 西藏
- 陕西
- 甘肃
- 青海
- 宁夏
- 新疆
- 台湾
- 香港
- 澳门
-
- -城市-
- -城市-
- 东城
- 西城
- 朝阳
- 丰台
- 石景山
- 海淀
- 门头沟
- 房山
- 通州
- 顺义
- 昌平
- 大兴
- 平谷
- 怀柔
- 密云
- 延庆
-
- -城市-
- 和平
- 河东
- 河西
- 南开
- 河北
- 红桥
- 滨海新区
- 东丽
- 西青
- 津南
- 北辰
- 宁河
- 武清
- 静海
- 宝坻
- 蓟县
-
- -城市-
- 石家庄
- 唐山
- 秦皇岛
- 邯郸
- 邢台
- 保定
- 张家口
- 承德
- 沧州
- 廊坊
- 衡水
-
- -城市-
- 太原
- 大同
- 阳泉
- 长治
- 晋城
- 朔州
- 晋中
- 运城
- 忻州
- 临汾
- 吕梁
-
- -城市-
- 呼和浩特
- 包头
- 乌海
- 赤峰
- 通辽
- 鄂尔多斯
- 呼伦贝尔
- 巴彦淖尔
- 乌兰察布
- 兴安
- 锡林郭勒
- 阿拉善
-
- -城市-
- 沈阳
- 大连
- 鞍山
- 抚顺
- 本溪
- 丹东
- 锦州
- 营口
- 阜新
- 辽阳
- 盘锦
- 铁岭
- 朝阳
- 葫芦岛
-
- -城市-
- 长春
- 吉林
- 四平
- 辽源
- 通化
- 白山
- 松原
- 白城
- 延边
-
- -城市-
- 哈尔滨
- 齐齐哈尔
- 鸡西
- 鹤岗
- 双鸭山
- 大庆
- 伊春
- 佳木斯
- 七台河
- 牡丹江
- 黑河
- 绥化
- 大兴安岭
-
- -城市-
- 黄浦
- 卢湾
- 徐汇
- 长宁
- 静安
- 普陀
- 闸北
- 虹口
- 杨浦
- 闵行
- 宝山
- 嘉定
- 浦东新区
- 金山
- 松江
- 奉贤
- 青浦
- 崇明
-
- -城市-
- 南京
- 无锡
- 徐州
- 常州
- 苏州
- 南通
- 连云港
- 淮安
- 盐城
- 扬州
- 镇江
- 泰州
- 宿迁
-
- -城市-
- 杭州
- 宁波
- 温州
- 嘉兴
- 湖州
- 绍兴
- 金华
- 衢州
- 舟山
- 台州
- 丽水
-
- -城市-
- 合肥
- 芜湖
- 蚌埠
- 淮南
- 马鞍山
- 淮北
- 铜陵
- 安庆
- 黄山
- 滁州
- 阜阳
- 宿州
- 六安
- 亳州
- 池州
- 宣城
-
- -城市-
- 福州
- 厦门
- 莆田
- 三明
- 泉州
- 漳州
- 南平
- 龙岩
- 宁德
-
- -城市-
- 南昌
- 景德镇
- 萍乡
- 九江
- 新余
- 鹰潭
- 赣州
- 吉安
- 宜春
- 抚州
- 上饶
-
- -城市-
- 济南
- 青岛
- 淄博
- 枣庄
- 东营
- 烟台
- 潍坊
- 济宁
- 泰安
- 威海
- 日照
- 莱芜
- 临沂
- 德州
- 聊城
- 滨州
- 菏泽
-
- -城市-
- 郑州
- 开封
- 洛阳
- 平顶山
- 安阳
- 鹤壁
- 新乡
- 焦作
- 濮阳
- 许昌
- 漯河
- 三门峡
- 南阳
- 商丘
- 信阳
- 周口
- 驻马店
- 济源
-
- -城市-
- 武汉
- 黄石
- 十堰
- 宜昌
- 襄阳
- 鄂州
- 荆门
- 孝感
- 荆州
- 黄冈
- 咸宁
- 随州
- 恩施
- 仙桃
- 潜江
- 天门
- 神农架
-
- -城市-
- 长沙
- 株洲
- 湘潭
- 衡阳
- 邵阳
- 岳阳
- 常德
- 张家界
- 益阳
- 郴州
- 永州
- 怀化
- 娄底
- 湘西
-
- -城市-
- 广州
- 韶关
- 深圳
- 珠海
- 汕头
- 佛山
- 江门
- 湛江
- 茂名
- 肇庆
- 惠州
- 梅州
- 汕尾
- 河源
- 阳江
- 清远
- 东莞
- 中山
- 潮州
- 揭阳
- 云浮
-
- -城市-
- 南宁
- 柳州
- 桂林
- 梧州
- 北海
- 防城港
- 钦州
- 贵港
- 玉林
- 百色
- 贺州
- 河池
- 来宾
- 崇左
-
- -城市-
- 海口
- 三亚
- 三沙
- 五指山
- 琼海
- 儋州
- 文昌
- 万宁
- 东方
- 定安
- 屯昌
- 澄迈
- 临高
- 白沙
- 昌江
- 乐东
- 陵水
- 保亭
- 琼中
-
- -城市-
- 万州
- 涪陵
- 渝中
- 大渡口
- 江北
- 沙坪坝
- 九龙坡
- 南岸
- 北碚
- 两江新区
- 万盛
- 双桥
- 渝北
- 巴南
- 长寿
- 綦江
- 潼南
- 铜梁
- 大足
- 荣昌
- 璧山
- 梁平
- 城口
- 丰都
- 垫江
- 武隆
- 忠县
- 开县
- 云阳
- 奉节
- 巫山
- 巫溪
- 黔江
- 石柱
- 秀山
- 酉阳
- 彭水
- 江津
- 合川
- 永川
- 南川
-
- -城市-
- 成都
- 自贡
- 攀枝花
- 泸州
- 德阳
- 绵阳
- 广元
- 遂宁
- 内江
- 乐山
- 南充
- 眉山
- 宜宾
- 广安
- 达州
- 雅安
- 巴中
- 资阳
- 阿坝
- 甘孜
- 凉山
-
- -城市-
- 贵阳
- 六盘水
- 遵义
- 安顺
- 铜仁
- 黔西南
- 毕节
- 黔东南
- 黔南
-
- -城市-
- 昆明
- 曲靖
- 玉溪
- 保山
- 昭通
- 丽江
- 普洱
- 临沧
- 楚雄
- 红河
- 文山
- 西双版纳
- 大理
- 德宏
- 怒江
- 迪庆
-
- -城市-
- 拉萨
- 昌都
- 山南
- 日喀则
- 那曲
- 阿里
- 林芝
-
- -城市-
- 西安
- 铜川
- 宝鸡
- 咸阳
- 渭南
- 延安
- 汉中
- 榆林
- 安康
- 商洛
-
- -城市-
- 兰州市
- 嘉峪关
- 金昌
- 白银
- 天水
- 武威
- 张掖
- 平凉
- 酒泉
- 庆阳
- 定西
- 陇南
- 临夏
- 甘南
-
- -城市-
- 西宁
- 海东
- 海北
- 黄南
- 海南
- 果洛
- 玉树
- 海西
-
- -城市-
- 银川
- 石嘴山
- 吴忠
- 固原
- 中卫
-
- -城市-
- 乌鲁木齐
- 克拉玛依
- 吐鲁番
- 哈密
- 昌吉
- 博尔塔拉
- 巴音郭楞
- 阿克苏
- 克孜勒苏
- 喀什
- 和田
- 伊犁
- 塔城
- 阿勒泰
- 石河子
- 阿拉尔
- 图木舒克
- 五家渠
- 北屯
-
- -城市-
- 台北市
- 高雄市
- 基隆市
- 台中市
- 台南市
- 新竹市
- 嘉义市
- 台北县
- 宜兰县
- 桃园县
- 新竹县
- 苗栗县
- 台中县
- 彰化县
- 南投县
- 云林县
- 嘉义县
- 台南县
- 高雄县
- 屏东县
- 台东县
- 花莲县
- 澎湖县
-
- -城市-
- 中西区
- 东区
- 九龙城区
- 观塘区
- 南区
- 深水埗区
- 黄大仙区
- 湾仔区
- 油尖旺区
- 离岛区
- 葵青区
- 北区
- 西贡区
- 沙田区
- 屯门区
- 大埔区
- 荃湾区
- 元朗区
-
- -城市-
- 花地玛堂区
- 圣安多尼堂区
- 大堂区
- 望德堂区
- 风顺堂区
- 氹仔
- 路环
-
import android.app.Dialog;
import android.content.Context;
import android.content.res.Resources;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AbsListView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
//R文件自己导包,我删掉了R文件的导包
public class Dialog1 extends Dialog {
private Context context;
private String province;
private Dialog1.ClickListenerInterface clickListenerInterface;
private String[] provinces,cities;
private Resources res;
private String selectedProvince;
private int currentProvince,currentCity;
private ListView lv_city,lv_province;
private ArrayAdapter adapter;
//实例化Diolog1,传入参数(调用Activity的context,之前选择过得省份城市)
public Dialog1(@NonNull Context context , String province) {
super(context, R.style.MyDialog);
this.context = context;
res =context.getResources();
selectedProvince = province;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
init();
}
private void init() {
//获取省份String数组
provinces=res.getStringArray(R.array.province);
//判断传进来的字符串是否为空
if (selectedProvince != null && !selectedProvince.isEmpty()){
//传进来的字符串不为空,用分隔符裁切成字符串数组
//传进来的字符串是类似这样的"北京 东城",我设置的是用两个空格分隔
String[] s = selectedProvince.split(" ");//这个分隔符要与UserInfoActivity设置的间隔符一致
//for循环对比是哪个省份,获取省份在数组中的第i位
for (int i = 0 ; i < provinces.length ; i++){
if (s[0].equals(provinces[i])){
currentProvince = i;
break;
}
}
//根据省份获取城市的字符串数组
cities = getCities(currentProvince -1);
//for循环对比是哪个城市,获取城市在数组中的第i位
for (int i = 0 ; i < cities.length ; i++){
if ( s[1] .equals(cities[i])){
currentCity = i;
break;
}
}
//设置默认的省份名称
province = s[0];
}else {
//传进来的省份城市字符串为空,则设置默认的省份为北京
cities = res.getStringArray(R.array.北京);
province = "北京";
}
//加载dialog布局
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.dialog1, null);
setContentView(view);
lv_province = view.findViewById(R.id.lv_dialog1_1);
lv_city = view.findViewById(R.id.lv_dialog1_2);
Button bt = view.findViewById(R.id.bt_dialog1);
bt.setOnClickListener(new clickListener());
//给省份listview设置适配器,并设置滑动到默认位置
// (注意:我们要让目标省份显示在中间,所以滑动到 currentProvince - 1 的位置)
lv_province.setAdapter(new ArrayAdapter(context,R.layout.item_dialog_lv,provinces));
lv_province.setSelection(currentProvince - 1);
//给省城市listview设置适配器,并设置滑动到默认位置
adapter = new ArrayAdapter(context,R.layout.item_dialog_lv,cities);
lv_city.setAdapter(adapter);
lv_city.setSelection(currentCity - 1);
/*
对省份listview设置滑动监听,滑动停止的时候给城市listview重新获取字符串数组,
并重新设置设置适配器(这一步应该是可以让适配器执行notifyDataSetChanged()的),
但是我对ArrayAdapter的notifyDataSetChanged()方法不太确定怎么用
*/
lv_province.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// OnScrollListener.SCROLL_STATE_IDLE:滚动停止时的状态
// OnScrollListener.SCROLL_STATE_STOUCH_SCROLL:触摸正在滚动,手指还没离开界面时的状态
// OnScrollListener.SCROLL_STATE_FLING:用户在用力滑动后,ListView由于惯性将继续滑动时的状态
if (scrollState == SCROLL_STATE_IDLE){
int position = lv_province.getFirstVisiblePosition() ;
province = provinces[position+1];
cities = getCities(position);
adapter = new ArrayAdapter(context,R.layout.item_dialog_lv,cities);
lv_city.setAdapter(adapter);
// adapter.notifyDataSetChanged();
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
}
});
}
public interface ClickListenerInterface {
//这里只设置了一个按钮,有需要可以自己添加
void doConfirm();
void doCancel();//可以设置多个方法和多个按钮对应
}
//监听点击按钮的回调
public void setClicklistener(Dialog1.ClickListenerInterface clickListenerInterface) {
this.clickListenerInterface = clickListenerInterface;
}
private class clickListener implements View.OnClickListener {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.bt_dialog1:
clickListenerInterface.doConfirm();
break;
//多个按钮在这添加case
default:
break;
}
}
}
//两个get方法
public String getProvince() {
return province;
}
public String getCity() {
return cities[lv_city.getFirstVisiblePosition()+1];
}
//根据省份获取城市字符串数组
private String[] getCities(int position){
switch (position){
case 0 :
cities = res.getStringArray(R.array.北京);
break;
case 1 :
cities = res.getStringArray(R.array.天津);
break;
case 2 :
cities = res.getStringArray(R.array.河北);
break;
case 3 :
cities = res.getStringArray(R.array.山西);
break;
case 4 :
cities = res.getStringArray(R.array.内蒙古);
break;
case 5 :
cities = res.getStringArray(R.array.辽宁);
break;
case 6 :
cities = res.getStringArray(R.array.吉林);
break;
case 7 :
cities = res.getStringArray(R.array.黑龙江);
break;
case 8 :
cities = res.getStringArray(R.array.上海);
break;
case 9 :
cities = res.getStringArray(R.array.江苏);
break;
case 10 :
cities = res.getStringArray(R.array.浙江);
break;
case 11 :
cities = res.getStringArray(R.array.安徽);
break;
case 12 :
cities = res.getStringArray(R.array.福建);
break;
case 13 :
cities = res.getStringArray(R.array.江西);
break;
case 14 :
cities = res.getStringArray(R.array.山东);
break;
case 15 :
cities = res.getStringArray(R.array.河南);
break;
case 16 :
cities = res.getStringArray(R.array.湖北);
break;
case 17 :
cities = res.getStringArray(R.array.湖南);
break;
case 18 :
cities = res.getStringArray(R.array.广东);
break;
case 19 :
cities = res.getStringArray(R.array.广西);
break;
case 20 :
cities = res.getStringArray(R.array.海南);
break;
case 21 :
cities = res.getStringArray(R.array.重庆);
break;
case 22 :
cities = res.getStringArray(R.array.四川);
break;
case 23 :
cities = res.getStringArray(R.array.贵州);
break;
case 24 :
cities = res.getStringArray(R.array.云南);
break;
case 25 :
cities = res.getStringArray(R.array.西藏);
break;
case 26 :
cities = res.getStringArray(R.array.陕西);
break;
case 27 :
cities = res.getStringArray(R.array.甘肃);
break;
case 28 :
cities = res.getStringArray(R.array.青海);
break;
case 29 :
cities = res.getStringArray(R.array.宁夏);
break;
case 30 :
cities = res.getStringArray(R.array.新疆);
break;
case 31 :
cities = res.getStringArray(R.array.台湾);
break;
case 32 :
cities = res.getStringArray(R.array.香港);
break;
case 33 :
cities = res.getStringArray(R.array.澳门);
break;
}
return cities;
}
}
<style name="MyDialog" parent="android:style/Theme.Dialog">
<!--背景颜色及和透明程度-->
<item name="android:windowBackground">@color/transparent</item>
<!--是否去除标题 -->
<item name="android:windowNoTitle">true</item>
<!--是否去除边框-->
<item name="android:windowFrame">@null</item>
<!--是否浮现在activity之上-->
<item name="android:windowIsFloating">true</item>
<!--是否模糊-->
<item name="android:backgroundDimEnabled">true</item>
<item name="android:windowFullscreen">false</item>
</style>
//在需要选择省份城市的地方设置监听,点击了就执行这个方法
private TextView tv_juzhu;
tv_juzhu = findViewById();
private void showDialog1(){
//实例化Dialog1
final Dialog1 dialog1 = new Dialog1(this,tv_juzhu.getText().toString());
dialog1.setCancelable(true);
dialog1.show();
dialog1.setClicklistener(new Dialog1.ClickListenerInterface() {
@Override
public void doConfirm() {
province = dialog1.getProvince();
city = dialog1.getCity();
dialog1.dismiss();
//这里设置两个空格分隔,Dialog1里面的分隔符要与这个一样
tv_juzhu.setText(province + " " +city);
}
@Override
public void doCancel() {
//这个方法没用上,有两个或多个按钮的话就用上了
}
});
}
以上就是全部内容了,如果帮助到大家,请留个赞和评论;
如有疑问,也可以交流交流。