Android 实现Dialog省市二级联动菜单,两个简单listview达到目的

声明:本文内容思路到实现都是本人完成,如有雷同纯属巧合,省市字符串数组内容是借用了别人的(具体是谁的没记下来,搜的时候看到实现效果不太一样,就借用了这一部分,在这里表示感谢和抱歉),转载本文请注明出处。

之前搜别人的好多都没有这样效果,所以就自己写了一个,一开始想到这样写的时候,还不确定能不能达到效果,刚写出来简单模型的时候发现效果挺接近的,就慢慢改成了这样,效果感觉挺好的。
有些布局控件和变量命名很随意,不要见怪。

个人觉得这个二级联动实现比较简单,但是有局限性,第一级菜单选项很多的话会比较麻烦,实现省市县三级菜单的话就更不可行了。
其实本文主要是实现Dialog省市二级联动菜单,listview数据的处理并不是很好,可以使用更高效的数据加载方式,不用像我这样把数据弄的这么麻烦。特别是switch case获取城市的数组数据,太麻烦了!

先上个效果图

Android 实现Dialog省市二级联动菜单,两个简单listview达到目的_第1张图片

先上dialog布局文件 ↓



    
        
        
            
            
            
                
                
            
            
            
        
    

item布局 ↓



    

几个背景图形 ↓ (颜色形状可以自行设置)
放在drawable文件夹下

//标题背景 shape_e6e6e6_top5dp



    
    

shape_ffffff_bottom_5dp



    
    

//按钮背景 shape_bg_c24333_5dp



    
    

下面是省份和城市的字符串数组,放在string.xml文件里面

数组最后都加了一个空数据,是为了让本来最后一个数据可以显示在中间位置


        -省份-
        北京
        天津
        河北
        山西
        内蒙古
        辽宁
        吉林
        黑龙江
        上海
        江苏
        浙江
        安徽
        福建
        江西
        山东
        河南
        湖北
        湖南
        广东
        广西
        海南
        重庆
        四川
        贵州
        云南
        西藏
        陕西
        甘肃
        青海
        宁夏
        新疆
        台湾
        香港
        澳门
          
    
    
        -城市-
    
    
        -城市-
        东城
        西城
        朝阳
        丰台
        石景山
        海淀
        门头沟
        房山
        通州
        顺义
        昌平
        大兴
        平谷
        怀柔
        密云
        延庆
          
    
    
        -城市-
        和平
        河东
        河西
        南开
        河北
        红桥
        滨海新区
        东丽
        西青
        津南
        北辰
        宁河
        武清
        静海
        宝坻
        蓟县
          
    
    
        -城市-
        石家庄
        唐山
        秦皇岛
        邯郸
        邢台
        保定
        张家口
        承德
        沧州
        廊坊
        衡水
          
    
    
        -城市-
        太原
        大同
        阳泉
        长治
        晋城
        朔州
        晋中
        运城
        忻州
        临汾
        吕梁
          
    
    
        -城市-
        呼和浩特
        包头
        乌海
        赤峰
        通辽
        鄂尔多斯
        呼伦贝尔
        巴彦淖尔
        乌兰察布
        兴安
        锡林郭勒
        阿拉善
          
    
    
        -城市-
        沈阳
        大连
        鞍山
        抚顺
        本溪
        丹东
        锦州
        营口
        阜新
        辽阳
        盘锦
        铁岭
        朝阳
        葫芦岛
          
    
    
        -城市-
        长春
        吉林
        四平
        辽源
        通化
        白山
        松原
        白城
        延边
          
    
    
        -城市-
        哈尔滨
        齐齐哈尔
        鸡西
        鹤岗
        双鸭山
        大庆
        伊春
        佳木斯
        七台河
        牡丹江
        黑河
        绥化
        大兴安岭
          
    
    
        -城市-
        黄浦
        卢湾
        徐汇
        长宁
        静安
        普陀
        闸北
        虹口
        杨浦
        闵行
        宝山
        嘉定
        浦东新区
        金山
        松江
        奉贤
        青浦
        崇明
          
    
    
        -城市-
        南京
        无锡
        徐州
        常州
        苏州
        南通
        连云港
        淮安
        盐城
        扬州
        镇江
        泰州
        宿迁
          
    
    
        -城市-
        杭州
        宁波
        温州
        嘉兴
        湖州
        绍兴
        金华
        衢州
        舟山
        台州
        丽水
          
    
    
        -城市-
        合肥
        芜湖
        蚌埠
        淮南
        马鞍山
        淮北
        铜陵
        安庆
        黄山
        滁州
        阜阳
        宿州
        六安
        亳州
        池州
        宣城
          
    
    
        -城市-
        福州
        厦门
        莆田
        三明
        泉州
        漳州
        南平
        龙岩
        宁德
          
    
    
        -城市-
        南昌
        景德镇
        萍乡
        九江
        新余
        鹰潭
        赣州
        吉安
        宜春
        抚州
        上饶
          
    
    
        -城市-
        济南
        青岛
        淄博
        枣庄
        东营
        烟台
        潍坊
        济宁
        泰安
        威海
        日照
        莱芜
        临沂
        德州
        聊城
        滨州
        菏泽
          
    
    
        -城市-
        郑州
        开封
        洛阳
        平顶山
        安阳
        鹤壁
        新乡
        焦作
        濮阳
        许昌
        漯河
        三门峡
        南阳
        商丘
        信阳
        周口
        驻马店
        济源
          
    
    
        -城市-
        武汉
        黄石
        十堰
        宜昌
        襄阳
        鄂州
        荆门
        孝感
        荆州
        黄冈
        咸宁
        随州
        恩施
        仙桃
        潜江
        天门
        神农架
          
    
    
        -城市-
        长沙
        株洲
        湘潭
        衡阳
        邵阳
        岳阳
        常德
        张家界
        益阳
        郴州
        永州
        怀化
        娄底
        湘西
          
    
    
        -城市-
        广州
        韶关
        深圳
        珠海
        汕头
        佛山
        江门
        湛江
        茂名
        肇庆
        惠州
        梅州
        汕尾
        河源
        阳江
        清远
        东莞
        中山
        潮州
        揭阳
        云浮
          
    
    
        -城市-
        南宁
        柳州
        桂林
        梧州
        北海
        防城港
        钦州
        贵港
        玉林
        百色
        贺州
        河池
        来宾
        崇左
          
    
    
        -城市-
        海口
        三亚
        三沙
        五指山
        琼海
        儋州
        文昌
        万宁
        东方
        定安
        屯昌
        澄迈
        临高
        白沙
        昌江
        乐东
        陵水
        保亭
        琼中
          
    
    
        -城市-
        万州
        涪陵
        渝中
        大渡口
        江北
        沙坪坝
        九龙坡
        南岸
        北碚
        两江新区
        万盛
        双桥
        渝北
        巴南
        长寿
        綦江
        潼南
        铜梁
        大足
        荣昌
        璧山
        梁平
        城口
        丰都
        垫江
        武隆
        忠县
        开县
        云阳
        奉节
        巫山
        巫溪
        黔江
        石柱
        秀山
        酉阳
        彭水
        江津
        合川
        永川
        南川
          
    
    
        -城市-
        成都
        自贡
        攀枝花
        泸州
        德阳
        绵阳
        广元
        遂宁
        内江
        乐山
        南充
        眉山
        宜宾
        广安
        达州
        雅安
        巴中
        资阳
        阿坝
        甘孜
        凉山
          
    
    
        -城市-
        贵阳
        六盘水
        遵义
        安顺
        铜仁
        黔西南
        毕节
        黔东南
        黔南
          
    
    
        -城市-
        昆明
        曲靖
        玉溪
        保山
        昭通
        丽江
        普洱
        临沧
        楚雄
        红河
        文山
        西双版纳
        大理
        德宏
        怒江
        迪庆
          
    
    
        -城市-
        拉萨
        昌都
        山南
        日喀则
        那曲
        阿里
        林芝
          
    
    
        -城市-
        西安
        铜川
        宝鸡
        咸阳
        渭南
        延安
        汉中
        榆林
        安康
        商洛
          
    
    
        -城市-
        兰州市
        嘉峪关
        金昌
        白银
        天水
        武威
        张掖
        平凉
        酒泉
        庆阳
        定西
        陇南
        临夏
        甘南
          
    
    
        -城市-
        西宁
        海东
        海北
        黄南
        海南
        果洛
        玉树
        海西
          
    
    
        -城市-
        银川
        石嘴山
        吴忠
        固原
        中卫
          
    
    
        -城市-
        乌鲁木齐
        克拉玛依
        吐鲁番
        哈密
        昌吉
        博尔塔拉
        巴音郭楞
        阿克苏
        克孜勒苏
        喀什
        和田
        伊犁
        塔城
        阿勒泰
        石河子
        阿拉尔
        图木舒克
        五家渠
        北屯
          
    
    
        -城市-
        台北市
        高雄市
        基隆市
        台中市
        台南市
        新竹市
        嘉义市
        台北县
        宜兰县
        桃园县
        新竹县
        苗栗县
        台中县
        彰化县
        南投县
        云林县
        嘉义县
        台南县
        高雄县
        屏东县
        台东县
        花莲县
        澎湖县
          
    
    
        -城市-
        中西区
        东区
        九龙城区
        观塘区
        南区
        深水埗区
        黄大仙区
        湾仔区
        油尖旺区
        离岛区
        葵青区
        北区
        西贡区
        沙田区
        屯门区
        大埔区
        荃湾区
        元朗区
          
    
    
        -城市-
        花地玛堂区
        圣安多尼堂区
        大堂区
        望德堂区
        风顺堂区
        氹仔
        路环
          
    

下面是自定义Dialog1 ↓

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;
    }
}

dialog的style MyDialog

<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>

下面是在activity中调用

//在需要选择省份城市的地方设置监听,点击了就执行这个方法

	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() {
                //这个方法没用上,有两个或多个按钮的话就用上了
            }
        });
    }

以上就是全部内容了,如果帮助到大家,请留个赞和评论;
如有疑问,也可以交流交流。

你可能感兴趣的:(Android 实现Dialog省市二级联动菜单,两个简单listview达到目的)