PickerView实现全国地址的选择

本文介绍了一种简化GitHub上PickerView控件数据填充的方法,通过解析预置的XML文件来快速填充省市县数据,避免了手动逐条填充的繁琐过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

GitHub有一个开源控件PickerView,可以实现三级联动的效果。虽然该控件使用非常简单,但是填充数据异常繁琐。GitHub上的Demo在填充数据的时候是一条一条地填充的,代码过于冗余。下面提供一种简便的方式来实现。

(1)在app目录下新建一个assets文件夹,将province_data.xml文件复制到该文件夹下,该XML文件里保存了全国的省市县的地址数据。
(2)使用SAX解析xml文件中的数据,并将数据填充到PickerView这个控件中。

—ProvinceModel—

public class ProvinceModel implements IPickerViewData
{
    private String name;
    private List<CityModel> cityList;

    public ProvinceModel()
    {
        super();
    }

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    public List<CityModel> getCityList()
    {
        return cityList;
    }

    public void setCityList(List<CityModel> cityList)
    {
        this.cityList = cityList;
    }

    @Override
    public String getPickerViewText()
    {
        return name;
    }
}

—CityModel—

public class CityModel implements IPickerViewData
{
    private String name;
    private List<DistrictModel> districtList;

    public CityModel()
    {
        super();
    }

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    public List<DistrictModel> getDistrictList()
    {
        return districtList;
    }

    public void setDistrictList(List<DistrictModel> districtList)
    {
        this.districtList = districtList;
    }

    @Override
    public String toString()
    {
        return name;
    }

    @Override
    public String getPickerViewText()
    {
        return name;
    }
}

—DistrictModel—

public class DistrictModel implements IPickerViewData
{
    private String name;
    private String zipcode;

    public DistrictModel()
    {
        super();
    }

    public String getZipcode()
    {
        return zipcode;
    }

    public void setZipcode(String zipcode)
    {
        this.zipcode = zipcode;
    }

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    @Override
    public String toString()
    {
        return name;
    }

    @Override
    public String getPickerViewText()
    {
        return name;
    }
}

—XmlParserHandler—

public class XmlParserHandler extends DefaultHandler
{
    /**
     *   存储所有的解析对象
     */
    private List<ProvinceModel> provinceList = new ArrayList<>();
    private ProvinceModel provinceModel = new ProvinceModel();
    private CityModel cityModel = new CityModel();
    private DistrictModel districtModel = new DistrictModel();

    public XmlParserHandler(){}

    public List<ProvinceModel> getDataList()
    {
        return provinceList;
    }

    @Override
    public void startDocument() throws SAXException
    {
        super.startDocument();
    }

    @Override
    public void endDocument() throws SAXException
    {
        super.endDocument();
    }

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
    {
        if (qName.equals("province"))
        {
            provinceModel = new ProvinceModel();
            provinceModel.setName(attributes.getValue(0));
            provinceModel.setCityList(new ArrayList<CityModel>());
        }
        else if (qName.equals("city"))
        {
            cityModel = new CityModel();
            cityModel.setName(attributes.getValue(0));
            cityModel.setDistrictList(new ArrayList<DistrictModel>());
        }
        else if (qName.equals("district"))
        {
            districtModel = new DistrictModel();
            districtModel.setName(attributes.getValue(0));
            districtModel.setZipcode(attributes.getValue(1));
        }
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException
    {
        if(qName.equals("district"))
        {
            cityModel.getDistrictList().add(districtModel);
        }
        else if(qName.equals("city"))
        {
            provinceModel.getCityList().add(cityModel);
        }
        else if(qName.equals("province"))
        {
            provinceList.add(provinceModel);
        }
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException
    {
        super.characters(ch, start, length);
    }
}
public class AddressAddActivity extends BaseActivity
{
    private OptionsPickerView mCityPickerView;
    private ArrayList<ProvinceModel> mProvinces = new ArrayList<>();
    private ArrayList<ArrayList<CityModel>> mCities = new ArrayList<>();
    private ArrayList<ArrayList<ArrayList<DistrictModel>>> mDistricts = new ArrayList<>();

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_address_add);
        ViewUtils.inject(this);
        init();
    }

    private void init()
    {
        initProvinceDatas();
        try
        {
            //选项选择器
            mCityPickerView = new OptionsPickerView(this);
            mCityPickerView.setPicker( mProvinces, mCities, mDistricts, true);
            mCityPickerView.setTitle("选择城市");
            mCityPickerView.setCyclic(false, false , false);
            mCityPickerView.setOnoptionsSelectListener(new OptionsPickerView.OnOptionsSelectListener() {
                @Override
                public void onOptionsSelect(int options1, int option2, int options3)
                {
                    String address = mProvinces.get(options1).getName() + "  "
                            + mCities.get(options1).get(option2) + "  "
                            + mDistricts.get(options1).get(option2).get(options3);
                    mTxtAddress.setText(address);
                }
            });
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    @OnClick(R.id.ll_city_picker)
    public void showpickerView(View view)
    {
        mCityPickerView.show();
    }

    protected void initProvinceDatas()
    {
        AssetManager asset = getAssets();
        try
        {
            InputStream input = asset.open("province_data.xml");
            SAXParserFactory spf = SAXParserFactory.newInstance();
            SAXParser parser = spf.newSAXParser();
            XmlParserHandler handler = new XmlParserHandler();
            parser.parse(input , handler);
            input.close();
            //获取解析出来的数据
            mProvinces = (ArrayList<ProvinceModel>) handler.getDataList();
        }
        catch (Throwable e)
        {
            e.printStackTrace();
        }

        if (mProvinces != null)
        {
            for (ProvinceModel p : mProvinces)
            {
                List<CityModel> cities = p.getCityList();
                //组装城市数据
                mCities.add((ArrayList<CityModel>) cities);
                ArrayList<ArrayList<DistrictModel>> dts = new ArrayList<>();
                for (CityModel c : cities)
                {
                    List<DistrictModel> districts = c.getDistrictList();
                    dts.add((ArrayList<DistrictModel>) districts);
                }
                mDistricts.add(dts);
            }
        }
    }
}

到此完毕,很简单的例子。

这是一个高仿 IOS PickerView 控件的库。代码来自:https://github.com/saiwu-bigkoo/Android-PickerView ,在原有代码基础上进行封装,并提供了一些修改属性方法。后期如有时间,将会对原有代码进行优化。预览使用首先需要在 build.gradle 文件中添加依赖:dependencies {    compile 'com.airsaid.library:pickerviewlibrary:1.0.0' }添加好依赖后,重新同步工程。可根据需求使用如下选择器:城市选择:        CityPickerView mCityPickerView = new CityPickerView(this);         // 设置点击外部是否消失 //        mCityPickerView.setCancelable(true);         // 设置滚轮字体大小 //        mCityPickerView.setTextSize(18f);         // 设置标题 //        mCityPickerView.setTitle("我是标题");         // 设置取消文字 //        mCityPickerView.setCancelText("我是取消文字");         // 设置取消文字颜色 //        mCityPickerView.setCancelTextColor(Color.GRAY);         // 设置取消文字大小 //        mCityPickerView.setCancelTextSize(14f);         // 设置确定文字 //        mCityPickerView.setSubmitText("我是确定文字");         // 设置确定文字颜色 //        mCityPickerView.setSubmitTextColor(Color.BLACK);         // 设置确定文字大小 //        mCityPickerView.setSubmitTextSize(14f);         // 设置头部背景 //        mCityPickerView.setHeadBackgroundColor(Color.RED);         mCityPickerView.setOnCitySelectListener(new CityPickerView.OnCitySelectListener() {             @Override             public void onCitySelect(String str) {                 Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show();             }         });         mCityPickerView.show();时间选择: //     TimePickerView 同样有上面设置样式的方法         TimePickerView mTimePickerView = new TimePickerView(this, TimePickerView.Type.YEAR_MONTH_DAY);         // 设置是否循环 //        mTimePickerView.setCyclic(true);         // 设置滚轮文字大小 //        mTimePickerView.setTextSize(TimePickerView.TextSize.SMALL);         // 设置时间可选范围(结合 setTime 方法使用,必须在) //        Calendar calendar = Calendar.getInstance(); //        mTimePickerView.setRange(calendar.get(Calendar.YEAR) - 100, calendar.get(Calendar.YEAR));         // 设置选中时间 //        mTimePickerView.setTime(new Date());         mTimePickerView.setOnTimeSelectListener(new TimePickerView.OnTimeSelectListener() {             @Override             public void onTimeSelect(Date date) {                 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd", Locale.CHINA);                 Toast.makeText(MainActivity.this, format.format(date), Toast.LENGTH_SHORT).show();             }         });         mTimePickerView.show();选项选择:        OptionsPickerView<String> mOptionsPickerView = new OptionsPickerView<>(this);         final ArrayList<String> list = new ArrayList<>();         list.add("男");         list.add("女");         // 设置数据         mOptionsPickerView.setPicker(list);         // 设置选项单位 //        mOptionsPickerView.setLabels("性");         mOptionsPickerView.setOnOptionsSelectListener(new OptionsPickerView.OnOptionsSelectListener() {             @Override             public void onOptionsSelect(int option1, int option2, int option3) {                 String sex = list.get(option1);                 Toast.makeText(MainActivity.this, sex, Toast.LENGTH_SHORT).show();             }         });         mOptionsPickerView.show();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值