android 省市区三级联动选择器

本文是点面具全(啰里八嗦)的纯码篇。

通过读取本地json文件显示数据,使用gson解析。
gradle中添加

//gson
compile ‘com.google.code.gson:gson:2.1’
//滚动选择器
compile ‘com.contrarywind:Android-PickerView:4.1.3’

AddressPickerDialog.java

public class AddressPickerDialog extends Dialog implements View.OnClickListener {

    private WheelView wvProvince, wvCity, wvArea;
    //弹出框的标题
    private String title;

    private Context mContext;

    private List<RegionProvinceBean> provinceBeans = null;

    AddressPickerDialog(Context context, String title, AddressPickerDialog.onAreaPickerDialogClickListener listener) {
        // 在构造方法里, 传入主题
        super(context, R.style.BottomDialogStyle);
        mContext = context;
        // 拿到Dialog的Window, 修改Window的属性
        Window window = getWindow();
        assert window != null;
        window.getDecorView().setPadding(0, 0, 0, 0);
        //获取当前屏幕的宽高
        DisplayMetrics dm = mContext.getResources().getDisplayMetrics();

        // 获取Window的LayoutParams
        WindowManager.LayoutParams attributes = window.getAttributes();
        attributes.width = WindowManager.LayoutParams.MATCH_PARENT;
        attributes.height = dm.heightPixels / 3;//默认显示高度为屏幕的三分之一
        attributes.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
        attributes.dimAmount = 0.3f;

        // 一定要重新设置, 才能生效
        window.setAttributes(attributes);
        window.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);

        this.title = title;
        this.listener = listener;
    }

    @SuppressLint("HandlerLeak")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.dialog_wheelview_address);

        initView();
        initData();
    }

    private void initView() {
        TextView tvAddressTitle = findViewById(R.id.tv_addresspicker_title);
        wvProvince = findViewById(R.id.wheelv_province);
        wvCity = findViewById(R.id.wheelv_city);
        wvArea = findViewById(R.id.wheelv_area);

        findViewById(R.id.tv_addresspicker_confirm).setOnClickListener(this);
        findViewById(R.id.tv_addresspicker_exit).setOnClickListener(this);

        if (!TextUtils.isEmpty(title)) tvAddressTitle.setText(title);
    }

    private RegionProvinceBean curPBean;
    private RegionCityBean curCBean;
    private RegionAreaBean curABean;

    private void initData() {
        String regionStr = getLocalJson();
        Gson gson = new Gson();
        RegionBean regionBean = gson.fromJson(regionStr, RegionBean.class);
        if (regionBean == null) {
            return;
        }
        provinceBeans = regionBean.getData();
        curPBean = provinceBeans.get(0);
        wvProvince.setCyclic(false);
        wvCity.setCyclic(false);
        wvArea.setCyclic(false);

        ArrayList<String> pList = new ArrayList<>();
        final ArrayList<String> cList = new ArrayList<>();
        final ArrayList<String> aList = new ArrayList<>();

        curPBean = provinceBeans.get(0);
        for (RegionProvinceBean p : provinceBeans) {
            pList.add(p.getAreaname());
        }
        wvProvince.setAdapter(new ArrayWheelAdapter<>(pList));
        wvProvince.setCurrentItem(0);

        curCBean = curPBean.getSubarea().get(0);
        for (RegionCityBean c : curPBean.getSubarea()) {
            cList.add(c.getAreaname());
        }
        wvCity.setAdapter(new ArrayWheelAdapter<>(cList));
        wvCity.setCurrentItem(0);

        curABean = curCBean.getSubarea().get(0);
        for (RegionAreaBean a : curCBean.getSubarea()) {
            aList.add(a.getAreaname());
        }
        wvArea.setAdapter(new ArrayWheelAdapter<>(aList));
        wvArea.setCurrentItem(0);

        wvProvince.setOnItemSelectedListener(new OnItemSelectedListener() {
            @Override
            public void onItemSelected(int index) {
                curPBean = provinceBeans.get(index);

                //联动第二级
                cList.clear();
                ArrayList<RegionCityBean> cBeans = curPBean.getSubarea();
                curCBean = cBeans.get(0);
                for (RegionCityBean c : cBeans) {
                    cList.add(c.getAreaname());
                }
                wvCity.setAdapter(new ArrayWheelAdapter<>(cList));
                wvCity.setCurrentItem(0);
                //联动第三级
                aList.clear();
                ArrayList<RegionAreaBean> aBeans = curCBean.getSubarea();
                curABean = aBeans.get(0);
                for (RegionAreaBean a : aBeans) {
                    aList.add(a.getAreaname());
                }
                wvArea.setAdapter(new ArrayWheelAdapter<>(aList));
                wvArea.setCurrentItem(0);
            }
        });
        wvCity.setOnItemSelectedListener(new OnItemSelectedListener() {
            @Override
            public void onItemSelected(int index) {
                curCBean = curPBean.getSubarea().get(index);

                //联动第三级
                aList.clear();
                ArrayList<RegionAreaBean> aBeans = curCBean.getSubarea();
                curABean = aBeans.get(0);
                for (RegionAreaBean a : aBeans) {
                    aList.add(a.getAreaname());
                }
                wvArea.setAdapter(new ArrayWheelAdapter<>(aList));
                wvArea.setCurrentItem(0);
            }
        });
        wvArea.setOnItemSelectedListener(new OnItemSelectedListener() {
            @Override
            public void onItemSelected(int index) {
                curABean = curCBean.getSubarea().get(index);
            }
        });
    }

    @Override
    public void onClick(View v) {
        RegionChoosedBean bean = new RegionChoosedBean();
        switch (v.getId()) {
            case R.id.tv_addresspicker_confirm:
                bean.setEmpty(false);
                bean.setpCode(curPBean.getAreacode());
                bean.setpName(curPBean.getAreaname());
                bean.setcCode(curCBean.getAreacode());
                bean.setcName(curCBean.getAreaname());
                bean.setaCode(curABean.getAreacode());
                bean.setaName(curABean.getAreaname());
                listener.onChooseClick(bean);
                break;
            case R.id.tv_addresspicker_exit:
                bean.setEmpty(true);
                listener.onChooseClick(bean);
                break;
        }
    }

    private AddressPickerDialog.onAreaPickerDialogClickListener listener;

    public interface onAreaPickerDialogClickListener {
        void onChooseClick(RegionChoosedBean bean);
    }

    /**
     * 获取本地json文件
     *
     * @return 本地json内容的字符串
     */
    private String getLocalJson() {
        StringBuilder builder = new StringBuilder();
        try {
            AssetManager assetManager = mContext.getAssets(); // 获得assets资源管理器(assets中的文件无法直接访问,可以使用AssetManager访问)
            InputStreamReader inputStreamReader = new InputStreamReader(assetManager.open("region.json"), "UTF-8");
            BufferedReader br = new BufferedReader(inputStreamReader);
            String line;
            while ((line = br.readLine()) != null) {
                builder.append(line);
            }
            br.close();
            inputStreamReader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return builder.toString();
    }
}

dialog_wheelview_address.xml

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

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:background="#c0eeea"
        android:gravity="center_vertical"
        android:orientation="horizontal"
        android:padding="20dp">

        <TextView
            android:id="@+id/tv_addresspicker_exit"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="取消"
            android:textColor="#287a72" />

        <TextView
            android:id="@+id/tv_addresspicker_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center"
            android:text="选择地区"
            android:textColor="#222" />

        <TextView
            android:id="@+id/tv_addresspicker_confirm"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="完成"
            android:textColor="#287a72" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:orientation="horizontal">

        <com.contrarywind.view.WheelView
            android:id="@+id/wheelv_province"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1" />

        <com.contrarywind.view.WheelView
            android:id="@+id/wheelv_city"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1" />

        <com.contrarywind.view.WheelView
            android:id="@+id/wheelv_area"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1" />

    </LinearLayout>

</LinearLayout>

Activity调用

 private AddressPickerDialog dialog = null;

    @OnClick(R.id.tv_choose_address)
    public void onViewClick(View v) {
        dialog = new AddressPickerDialog(mContext,"弹出框标题", new AddressPickerDialog.onAreaPickerDialogClickListener() {
            @Override
            public void onChooseClick(RegionChoosedBean bean) {
            //bean 为点击完成返回的数据对象
                if (bean.isEmpty()) {
                    tvAddress.setText("未选择数据");
                } else {
                    tvAddress.setText(bean.getpName() + "\t" + bean.getcName() + "\t" + bean.getaName());
                }
                dialog.cancel();
            }
        });
        dialog.show();
   }

json字符串对应的实体类

public class RegionBean {
private ArrayList data;
public ArrayList getData() {
return data;
}
public void setData(ArrayList data) {
this.data = data;
}
}

实体类

//省
public class RegionProvinceBean {
private String areacode;
private String areaname;
private ArrayList subarea;
public String getAreacode() {
return areacode;
}
public void setAreacode(String areacode) {
this.areacode = areacode;
}
public String getAreaname() {
return areaname;
}
public void setAreaname(String areaname) {
this.areaname = areaname;
}
public ArrayList getSubarea() {
return subarea;
}
public void setSubarea(ArrayList subarea) {
this.subarea = subarea;
}
}
//市
public class RegionCityBean {
private String areacode;
private String areaname;
private ArrayList subarea;
public String getAreacode() {
return areacode;
}
public void setAreacode(String areacode) {
this.areacode = areacode;
}
public String getAreaname() {
return areaname;
}
public void setAreaname(String areaname) {
this.areaname = areaname;
}
public ArrayList getSubarea() {
return subarea;
}
public void setSubarea(ArrayList subarea) {
this.subarea = subarea;
}
}
//区
public class RegionAreaBean {
private String areacode;
private String areaname;
public String getAreacode() {
return areacode;
}
public void setAreacode(String areacode) {
this.areacode = areacode;
}
public String getAreaname() {
return areaname;
}
public void setAreaname(String areaname) {
this.areaname = areaname;
}
}

省市区json数据下载:https://download.csdn.net/download/qq_28026283/10500611

本文参考:https://github.com/Bigkoo/Android-PickerView
参考文章作者已经封装了数据类型为集合的省市区三级联动,个人习惯了实体类去处理,所以还是自己借用WheelView写了[比心][比心][比心]

猜你喜欢

转载自blog.csdn.net/qq_28026283/article/details/80416838