【达内课程】解析xml实现省份联动

文章目录


今天利用前两节学过的 dom4j 解析xml 和 pull 解析xml 来实现省份联动。旨在说明原理,github 上已经有了好多省份联动的轮子,我们不必重复造。

效果图

这里写图片描述

实现

1、准备省份数据 provinces.xml

我们只准备部分数据,搞懂原理,避免数据太多搞错重点…

<Provinces>
   <Province ID="1" ProvinceName="北京市">北京市</Province>
   <Province ID="2" ProvinceName="天津市">天津市</Province>
   <Province ID="3" ProvinceName="河北省">河北省</Province>
   <Province ID="4" ProvinceName="山西省">山西省</Province>
   <Province ID="5" ProvinceName="内蒙古自治区">内蒙古自治区</Province>
</Provinces>

准备城市数据 cities.xml

<?xml version="1.0" encoding="utf-8"?>
<Cities>
    <City ID="1" CityName="北京" PID="1" ZipCode="100000">北京</City>
    <City ID="2" CityName="天津" PID="2" ZipCode="100000">天津</City>
    <City ID="3" CityName="石家庄" PID="3" ZipCode="050000">石家庄</City>
    <City ID="4" CityName="唐山" PID="3" ZipCode="063000">唐山</City>
    <City ID="5" CityName="秦皇岛" PID="3" ZipCode="066000">秦皇岛</City>
    <City ID="14" CityName="太原" PID="4" ZipCode="030000">太原</City>
    <City ID="15" CityName="大同" PID="1" ZipCode="037000">大同</City>
    <City ID="25" CityName="呼和浩特" PID="5" ZipCode="010000">呼和浩特</City>
</Cities>

用 Province.java 来描述一个省份

public class Province {
    private int id;
    private String name;

    public Province() {
    }

    public Province(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

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

用 City.java 来描述一个城市

public class City {
    private int id;
    private int pid;
    private String name;

    public City() {
    }

    public City(int id, int pid, String name) {
        this.id = id;
        this.pid = pid;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getPid() {
        return pid;
    }

    public void setPid(int pid) {
        this.pid = pid;
    }

    public String getName() {
        return name;
    }

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

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

布局文件 activity_test.xml
在布局文件中放两个 ListView 分别用来展示省份 以及 点击省份展示出来的城市

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ListView
        android:id="@+id/lvProvince"
        android:layout_width="0dp"
        android:layout_height="300dp"
        android:layout_weight="1" />

    <ListView
        android:id="@+id/lvCity"
        android:layout_width="0dp"
        android:layout_height="300dp"
        android:layout_weight="1" />

</LinearLayout>

在 TestActivity 中编写代码,我们分别用学过的 dom4j解析xmlpull解析xml

public class TestActivity extends Activity {
    private ListView lvProvince;
    private ListView lvCity;
    List<Province> provinces;
    private List<City> allCities;
    private List<City> cities = new ArrayList<City>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);

        setViews();
        try {
            //解析省份的xml
            parseAndLoadProvince();
            parseCity();
        } catch (Exception e) {
            e.printStackTrace();
        }

        setListeners();
    }

    private void setViews() {
        lvProvince = findViewById(R.id.lvProvince);
        lvCity = findViewById(R.id.lvCity);
    }

    /**
     * 解析并加载省份信息(DOM4J)
     */
    private void parseAndLoadProvince() throws Exception {
        SAXReader reader = new SAXReader();
        InputStream is = getAssets().open("provinces.xml");
        Document doc = reader.read(is);
        //获取文档根元素
        Element root = doc.getRootElement();
        List<Element> proEles = root.elements();
        provinces = new ArrayList<Province>();
        for (Element e : proEles) {
            //获取省份ID和省份名称
            String id = e.attributeValue("ID");
            String name = e.attributeValue("ProvinceName");
            Province p = new Province(Integer.parseInt(id), name);
            provinces.add(p);
        }
        //解析完毕,立即显示到界面中
        ArrayAdapter<Province> adapter = new ArrayAdapter<Province>(this, android.R.layout.simple_list_item_1, provinces);
        lvProvince.setAdapter(adapter);
    }

    /**
     * 解析所有城市数据并保存到成员变量
     * 适合使用PULL解析
     */
    private void parseCity() throws Exception {
        XmlPullParser parser = Xml.newPullParser();
        InputStream is = getAssets().open("cities.xml");
        parser.setInput(is, "utf-8");
        int type = parser.getEventType();
        allCities = new ArrayList<City>();
        City city = null;
        while (type != XmlPullParser.END_DOCUMENT) {
            switch (type) {
                //碰到了开始标记
                case XmlPullParser.START_TAG:
                    String name = parser.getName();
                    if (name.equals("City")) {//创建对象
                        city = new City();
                        city.setId(Integer.parseInt(parser.getAttributeValue(0)));
                        city.setName(parser.getAttributeValue(1));
                        city.setPid(Integer.parseInt(parser.getAttributeValue(2)));
                        allCities.add(city);
                    }
                    break;
                default:
                    break;
            }
            type = parser.next();
        }
    }

    /**
     * 设置监听
     */
    private void setListeners() {
        lvProvince.setOnItemClickListener((adapterView, view, i, l) -> {
            //获取当前选中的是哪个省份
            Province p = provinces.get(i);
            int pid = p.getId();
            //遍历allCities 过滤所有需要的城市数据
            cities.clear();
            for (City c : allCities) {
                if (c.getPid() == pid) {
                    cities.add(c);
                }
            }
            //更新adapter
            ArrayAdapter<City> city = new ArrayAdapter<City>(TestActivity.this, android.R.layout.simple_list_item_1, cities);
            lvCity.setAdapter(city);
        });
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
省市联动XML <?xml version="1.0" encoding="utf-8"?> <china> <province name="北京"> <city>东城区</city> <city>西城区</city> <city>崇文区</city> <city>宣武区</city> <city>朝阳区</city> <city>丰台区</city> <city>石景山区</city> <city>海淀区</city> <city>门头沟区</city> <city>房山区</city> <city>通州区</city> <city>顺义区</city> <city>昌平区</city> <city>大兴区</city> <city>怀柔区</city> <city>平谷区</city> <city>密云县</city> <city>延庆县</city> </province> <province name="天津"> <city>和平区</city> <city>河东区</city> <city>河西区</city> <city>南开区</city> <city>河北区</city> <city>红桥区</city> <city>塘沽区</city> <city>汉沽区</city> <city>大港区</city> <city>东丽区</city> <city>西青区</city> <city>津南区</city> <city>北辰区</city> <city>武清区</city> <city>宝坻区</city> <city>宁河县</city> <city>静海县</city> <city>蓟县</city> </province> <province name="河北"> <city>石家庄</city> <city>唐山</city> <city>秦皇岛</city> <city>邯郸</city> <city>邢台</city> <city>保定</city> <city>张家口</city> <city>承德</city> <city>沧州</city> <city>廊坊</city> <city>衡水</city> </province> <province name="山西"> <city>太原</city> <city>大同</city> <city>阳泉</city> <city>长治</city> <city>晋城</city> <city>朔州</city> <city>晋中</city> <city>运城</city> <city>忻州</city> <city>临汾</city> <city>吕梁</city> </province> <province name="内蒙古"> <city>呼和浩特</city> <city>包头</city> <city>乌海</city> <city>赤峰</city> <city>通辽</city> <city>鄂尔多斯</city> <city>呼伦贝尔</city> <city>巴彦淖尔</city> <city>乌兰察布</city> <city>兴安盟</city> <city>锡林郭勒盟</city> <city>阿拉善盟</city> </province> <province name="辽宁"> <city>沈阳</city> <city>大连</city> <city>鞍山</city> <city>抚顺</city> <city>本溪</city> <city>丹东</city> <city>锦州</city> <city>营口</city> <city>阜新</city> <city>辽阳</city> <city>盘锦</city> <city>铁岭</city> <city>朝阳</city> <city>葫芦岛</city> </province> <province name="吉林"> <city>长春</city> <city>吉林</city> <city>四平</city> <city>辽源</city> <city>通化</city> <city>白山</city> <city>松原</city> <city>白城</city> <city>延边</city> </province> <province name="黑龙江"> <city>哈尔滨</city> <city>齐齐哈尔</city> <city>鸡西</city> <city>鹤岗</city> <city>双鸭山</city> <city>大庆</city> <city>伊春</city> <city>佳木斯</city> <city>七台河</city> <city>牡丹江</city> <city>黑河</city> <city>绥化</city> <city>大兴安岭</city> </province> <province name="上海"> <city>黄浦区</city> <city>卢湾区</city> <city>徐汇区</city> <city>长宁区</city> <city>静安区</city> <city>普陀区</city> <city>闸北区</city> <city>虹口区</city> <city>杨浦区</city> <city>闵行区</city> <city>宝山区</city> <city>嘉定区</city> <city>浦东新区</city> <city>金山区</city> <city>松江区</city> <city>青浦区</city> <city>南汇区</city> <city>奉贤区</city> <city>崇明县</city> </province> <province name="江苏"> <city>南京</city> <city>无锡</city> <city>徐州</city> <city>常州</city> <city>苏州</city> <city>南通</city> <city>连云港</city> <city>淮安</city> <city>盐城</city> <city>扬州</city> <city>镇江</city> <city>泰州</city> <city>宿迁</city> </province> <province name="浙江"> <city>杭州</city> <city>宁波</city> <city>温州</city> <city>嘉兴</city> <city>湖州</city> <city>绍兴</city> <city>金华</city> <city>衢州</city> <city>舟山</city> <city>台州</city> <city>丽水</city> </province> <province name="安徽"> <city>合肥</city> <city>芜湖</city> <city>蚌埠</city> <city>淮南</city> <city>马鞍山</city> <city>淮北</city> <city>铜陵</city> <city>安庆</city> <city>黄山</city> <city>滁州</city> <city>阜阳</city> <city>宿州</city> <city>巢湖</city> <city>六安</city> <city>亳州</city> <city>池州</city> <city>宣城</city> </province> <province name="福建"> <city>福州</city> <city>厦门</city> <city>莆田</city> <city>三明</city> <city>泉州</city> <city>漳州</city> <city>南平</city> <city>龙岩</city> <city>宁德</city> </province> <province name="江西"> <city>南昌</city> <city>景德镇</city> <city>萍乡</city> <city>九江</city> <city>新余</city> <city>鹰潭</city> <city>赣州</city> <city>吉安</city> <city>宜春</city> <city>抚州</city> <city>上饶</city> </province> <province name="山东"> <city>济南</city> <city>青岛</city> <city>淄博</city> <city>枣庄</city> <city>东营</city> <city>烟台</city> <city>潍坊</city> <city>济宁</city> <city>泰安</city> <city>威海</city> <city>日照</city> <city>莱芜</city> <city>临沂</city> <city>德州</city> <city>聊城</city> <city>滨州</city> <city>荷泽</city> </province> <province name="河南"> <city>郑州</city> <city>开封</city> <city>洛阳</city> <city>平顶山</city> <city>安阳</city> <city>鹤壁</city> <city>新乡</city> <city>焦作</city> <city>濮阳</city> <city>许昌</city> <city>漯河</city> <city>三门峡</city> <city>南阳</city> <city>商丘</city> <city>信阳</city> <city>周口</city> <city>驻马店</city> </province> <province name="湖北"> <city>武汉</city> <city>黄石</city> <city>十堰</city> <city>宜昌</city> <city>襄樊</city> <city>鄂州</city> <city>荆门</city> <city>孝感</city> <city>荆州</city> <city>黄冈</city> <city>咸宁</city> <city>随州</city> <city>恩施</city> <city>神农架</city> </province> <province name="湖南"> <city>长沙</city> <
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值