Android菜鸟的成长笔记——Spinner 省市县三级地址选择

一、 准备数据

在网上找了一份xml的数据源,链接在这:http://pan.baidu.com/s/1pJoHosr

在res文件夹下新建一个xml文件夹,将解压得到的3个xml文件放进去。

二、 解析xml文件

先看一下xml文件吧,是这个格式的

<resources>

    <Province ID="0" ProvinceName="请选择">请选择  </Province>
解析代码如下:
public ArrayList<Province> getProvincesInfo()
    {
        //设置xml解析器,为读取的数据创建ArrayList对象
        XmlResourceParser xrp = getResources().getXml(R.xml.provinces);
        ArrayList<Province> provinces = new ArrayList<>();
        try
        {
            int eventType = xrp.getEventType();
            while (eventType != XmlResourceParser.END_DOCUMENT)
            {
                //当内容标签开始时,读取相应标签的属性
                if (eventType == XmlResourceParser.START_TAG && xrp.getName().equals("Province"))
                {
                    String id = xrp.getAttributeValue(null, "ID");
                    String name = xrp.getAttributeValue(null, "ProvinceName");
                    provinces.add(new Province(Integer.parseInt(id), name));
                }
                eventType = xrp.next();
            }
        } catch (XmlPullParserException | IOException e)
        {
            e.printStackTrace();
        }
        xrp.close();
        return provinces;
    }

三、绑定数据

将数据信息读到ArrayList对象中就好办了,直接用ArrayAdapter绑定就可以了:

        //为控件绑定视图
        Spinner spnProvince = (Spinner)findViewById(R.id.spnProvince);

        //读取并绑定province数据
        final ArrayList<Province> provinces = getProvincesInfo();
        final ArrayAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1,provinces);
        spnProvince.setAdapter(adapter);
因为ArrayList对象中的数据为自定义的Province,在Spinner中显示时会调用toString()函数,所以要在Province中重写toString函数,返回省份名称。

城市、和区域的选择都要依赖于上级的信息,在读取城市信息的时候需要传入省份的ID,来获取对应的城市,可以在读取标签属性的时候,判断传入的PID与读取的PID是否相等,来获取城市列表。

四、设置监听,实现城市和区域选择

数据绑定玩之后,就要设置监听了。

省份数据,在Activity onCreate的时候读入;城市数据,在选择了省份之后读入;区域数据在选择了城市之后读入。设置spnProvince的监听如下,在监听中读取数据,初始化子控件:

        //为Province设置监听
        spnProvince.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
        {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
            {
                //初始化城市列表
                initSpnCity((int) id);

                //选中“请选择”时不设置地址显示
                if (id == 0)
                {
                    //清空City、District选项
                    strProvince = "";
                    strCity = "";
                    strDistrict = "";
                } else
                {
                    strProvince = provinces.get((int) id).getName();
                }

                //显示选中的地址
                tvAddress.setText(ADDRESS_TITLE + "  " + strProvince + "  " + strCity + "  " + strDistrict);
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent)
            {

            }
        });
到此,三级地址选择就搞定了 大笑效果图 Android菜鸟的成长笔记——Spinner 省市县三级地址选择_第1张图片

下面是源码,Province、City、District的实现代码就不贴了,记得重写toString()方法返回名称就可以了。

package com.lcy.demo.studydemo;

import android.content.res.XmlResourceParser;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;
import com.lcy.demo.studydemo.address.City;
import com.lcy.demo.studydemo.address.District;
import com.lcy.demo.studydemo.address.Province;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.util.ArrayList;

/**
 * Created by loucyin on 2015/10/8.
 */
public class SpinnerActivity extends AppCompatActivity
{
    public static final String ADDRESS_TITLE = "您选择的地址是:";
    TextView tvAddress;
    String strProvince = "";
    String strCity = "";
    String strDistrict = "";
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_spinner);
        //绑定地址显示TextView
        tvAddress = (TextView)findViewById(R.id.tvAddress);

        //初始化spinner控件
        initSpnProvince();
    }

     //初始化spnProvince控件,并为其绑定数据,设置监听
    public void initSpnProvince()
    {
        //为控件绑定视图
        Spinner spnProvince = (Spinner)findViewById(R.id.spnProvince);

        //读取并绑定province数据
        final ArrayList<Province> provinces = getProvincesInfo();
        final ArrayAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1,provinces);
        spnProvince.setAdapter(adapter);

        //为Province设置监听
        spnProvince.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
        {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
            {
                //初始化城市列表
                initSpnCity((int) id);

                //选中“请选择”时不设置地址显示
                if (id == 0)
                {
                    //清空City、District选项
                    strProvince = "";
                    strCity = "";
                    strDistrict = "";
                } else
                {
                    strProvince = provinces.get((int) id).getName();
                }

                //显示选中的地址
                tvAddress.setText(ADDRESS_TITLE + "  " + strProvince + "  " + strCity + "  " + strDistrict);
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent)
            {

            }
        });
    }

    //初始化spnCity,并为其绑定数据,设置监听
    public void initSpnCity(int provinceId)
    {
        //为控件绑定视图
        final Spinner spnCity = (Spinner)findViewById(R.id.spnCity);

        //读取并绑定province数据
        final ArrayList<City> cities = getCitiesInfo(provinceId);
        ArrayAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1,cities);
        spnCity.setAdapter(adapter);

        //为Province设置监听
        spnCity.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
        {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
            {
                //获取城市ID,并初始化区域列表
                int cid = cities.get((int) id).getId();
                initSpnDistrict(cid);

                //选中“请选择”时不设置地址显示
                if(id == 0)
                {
                    strCity = "";
                    strDistrict = "";
                }
                else
                {
                    strCity = cities.get((int) id).getName();
                }

                //显示选中的地址
                tvAddress.setText(ADDRESS_TITLE + "  " + strProvince + "  " + strCity + "  " + strDistrict);
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent)
            {

            }
        });
    }

    //初始化spnDistrict控件,绑定数据,设置监听
    public void initSpnDistrict(int cityId)
    {
        //为控件绑定视图
        final Spinner spnDistrict = (Spinner)findViewById(R.id.spnDistrict);

        //读取并绑定province数据
        final ArrayList<District> districts = getDistrictInfo(cityId);
        ArrayAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1,districts);
        spnDistrict.setAdapter(adapter);

        spnDistrict.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
        {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
            {
                //选中“请选择”时不设置地址显示
                if (id == 0)
                {
                    strDistrict = "";
                } else
                {
                    strDistrict = districts.get((int) id).getName();

                }

                //显示选中的地址
                tvAddress.setText(ADDRESS_TITLE + "  " + strProvince + "  " + strCity + "  " + strDistrict);
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent)
            {

            }
        });
    }

    /**
     * @description 从文件中获取省份信息
     * @return 返回省份的ArrayList对象
     */
    public ArrayList<Province> getProvincesInfo()
    {
        //设置xml解析器,为读取的数据创建ArrayList对象
        XmlResourceParser xrp = getResources().getXml(R.xml.provinces);
        ArrayList<Province> provinces = new ArrayList<>();
        try
        {
            int eventType = xrp.getEventType();
            while (eventType != XmlResourceParser.END_DOCUMENT)
            {
                //当内容标签开始时,读取相应标签的属性
                if (eventType == XmlResourceParser.START_TAG && xrp.getName().equals("Province"))
                {
                    String id = xrp.getAttributeValue(null, "ID");
                    String name = xrp.getAttributeValue(null, "ProvinceName");
                    provinces.add(new Province(Integer.parseInt(id), name));
                }
                eventType = xrp.next();
            }
        } catch (XmlPullParserException | IOException e)
        {
            e.printStackTrace();
        }
        xrp.close();
        return provinces;
    }

    /**
     * @description 输入省份ID,获取对应的城市
     * @param provinceId 省份ID,用于在选择其对应的城市
     * @return 返回所包含城市的ArrayList对象
     */
    public ArrayList<City> getCitiesInfo(int provinceId)
    {
        //设置xml解析器,为读取的数据创建ArrayList对象
        XmlResourceParser xrp = getResources().getXml(R.xml.cities);
        ArrayList<City> cities = new ArrayList<>();
        cities.add(new City(0,0,"请选择",""));
        try
        {
            int eventType = xrp.getEventType();
            while (eventType != XmlResourceParser.END_DOCUMENT)
            {
                //当内容标签开始时,读取相应标签的属性
                if (eventType == XmlResourceParser.START_TAG && xrp.getName().equals("City"))
                {
                    String pid = xrp.getAttributeValue(null, "PID");
                    if (provinceId == Integer.parseInt(pid))
                    {
                        String id = xrp.getAttributeValue(null, "ID");
                        String zipCode = xrp.getAttributeValue(null, "ZipCode");
                        String name = xrp.getAttributeValue(null, "CityName");
                        cities.add(new City(Integer.parseInt(id), Integer.parseInt(pid), name, zipCode));
                    }
                }
                eventType = xrp.next();
            }
        } catch (XmlPullParserException | IOException e)
        {
            e.printStackTrace();
        }
        xrp.close();
        return cities;
    }

    /**
     * @description 输入城市ID,获取对应的区域
     * @param cityId 城市ID,用于在选择其对应的区域
     * @return 返回所包含区域的ArrayList对象
     */
    public ArrayList<District> getDistrictInfo(int cityId)
    {
        //设置xml解析器,为读取的数据创建ArrayList对象
        XmlResourceParser xrp = getResources().getXml(R.xml.districts);
        ArrayList<District> districts = new ArrayList<>();
        districts.add(new District(0,0,"请选择"));
        try
        {
            int eventType = xrp.getEventType();
            while (eventType != XmlResourceParser.END_DOCUMENT)
            {
                //当内容标签开始时,读取相应标签的属性
                if (eventType == XmlResourceParser.START_TAG && xrp.getName().equals("District"))
                {
                    String cid = xrp.getAttributeValue(null, "CID");
                    if (cityId == Integer.parseInt(cid))
                    {
                        String id = xrp.getAttributeValue(null, "ID");
                        String name = xrp.getAttributeValue(null, "DistrictName");
                        districts.add(new District(Integer.parseInt(id), cityId, name));
                    }
                }
                eventType = xrp.next();
            }
        } catch (XmlPullParserException | IOException e)
        {
            e.printStackTrace();
        }
        xrp.close();
        return districts;
    }
}

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
    >

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/material_grey_300">

        <TextView
            android:layout_width="80dp"
            android:layout_height="50dp"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:text="省份:"
            android:id="@+id/textView"
            android:gravity="center_vertical|center_horizontal"
            android:textColor="@android:color/holo_red_light"/>

        <Spinner
            android:layout_width="fill_parent"
            android:layout_height="50dp"
            android:id="@+id/spnProvince"
            android:spinnerMode="dropdown"/>
    </LinearLayout>

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/material_grey_100">

        <TextView
            android:layout_width="80dp"
            android:layout_height="50dp"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:text="城市:"
            android:id="@+id/textView2"
            android:gravity="center_vertical|center_horizontal"
            android:textColor="@android:color/holo_blue_bright"/>

        <Spinner
            android:layout_width="fill_parent"
            android:layout_height="50dp"
            android:id="@+id/spnCity"
            android:spinnerMode="dropdown"/>
    </LinearLayout>

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/material_grey_300">

        <TextView
            android:layout_width="80dp"
            android:layout_height="50dp"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:text="区域:"
            android:id="@+id/textView3"
            android:gravity="center_vertical|center_horizontal"
            android:textColor="@android:color/holo_green_dark"/>

        <Spinner
            android:layout_width="fill_parent"
            android:layout_height="50dp"
            android:id="@+id/spnDistrict"
            android:spinnerMode="dropdown"/>
    </LinearLayout>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="@string/Address"
        android:id="@+id/tvAddress"
        android:gravity="center_vertical"
        android:paddingLeft="15dp"
        android:paddingTop="20dp"
        android:paddingRight="20dp"
        android:paddingBottom="20dp"
        android:background="@color/material_grey_100"
        android:textColor="@android:color/holo_orange_dark"/>
</LinearLayout>




你可能感兴趣的:(android)