[Android]中国大部分城市地区的结构定义与按拼音排序

本文介绍了如何在Android中构建一个用于存储中国城市和地区数据的Hashtable结构,并详细阐述了数据层级及类型定义。通过ChinaCityUtil工具类,实现了获取不同行政区级别的方法,并讨论了在按拼音排序时遇到的特殊情况,如“重庆市”的排序问题及其解决方案。
摘要由CSDN通过智能技术生成
项目中涉及到送货地址,录入工作量挺耗时的,分享出来,减免大家的重复劳动。

先见效果图如下:

          





本示例中使用Hashtable记录了中国大部分城市与地区的数据。其结构如下:

Hashtable(Head)
    ↑
↑←←←←←←←←←←←←(key,Hashtable<key,String[]>)
    ↑
↑←←←←←←←←←←←←("福建省",Hashtable<"福州市",{"仓山区"、"晋安区"... ...}>)
 
这个数据结构封装在了ChinaCityUtil工具类中。该类中定义了三种行政区类型,分别为:
TYPE_PROVINCE 省、直辖市、自治区级别
TYPE_CITY 城市
TYPE_REGION 城区

TYPE_PROVINCE级别的名称都是Hashtable(Head)的Key值集合,TYPE_CITY级别的名称是子Hashtable的Key值集合,TYPE_REGION级别的名称则直接就是String数组了。则很明确,为了获取Hashtable中Key值的集合,此处实现了一个方法getKeyArrayByTable(Hashtable<String, ? extends Object>)。

ChinaCityUtil中实现的另一个重要方法为findAreaStringArr(Hashtable<String, Hashtable<String, String[]>> table,
int type, String... args),该方法的最后一个参数args为指定想要获取的地区。如想获取"福建省"或"福建省"下"福州市"的所有区级别地区名称,则执行:

			String[] arrCity = findAreaStringArr(hashtableHead,TYPE_REGION,"福建省");
			String[] arrRegion = findAreaStringArr(hashtableHead,TYPE_REGION,"福建省","福州市");



由于Hashtable取key值时是无序的,为了方便用户选择地区,还需要对取得的数组进行按拼音排序。Java中,Collator可实现此功能。Collator在Comparator实例化后,通过ArrayAdapter.sort(comparator)与显示地区数组的适配器结合起来进行排序。

在开发过程中,会发现“重庆市”竟然排在了最后,究其原因为“重”在程序中被以拼音“zhong”的第四音进行排序了。为让以"chong"第二音进行排序,则在Comparator.compare(Strin obj1,String obj2)方法中在其进行比较顺序之前执行如下代码:

	String	obj1 = obj1.replace("重庆", "崇庆");
	String	obj2 = obj2.replace("重庆", "崇庆");

以同样为"chong"第四音的"崇"字进行排序即可。

完整代码如下:


ChinaCityAct.java

package lab.sodino.chinacity;

import java.util.Hashtable;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;

/**
 * @author Sodino E-mail:sodinoopen@hotmail.com
 * @version Time:2011-8-20 下午08:41:25
 */
public class ChinaCityAct extends Activity implements AdapterView.OnItemSelectedListener {
	private ChinaAlphabetComparator comparator;
	private Spinner spinnerProvince;
	private Spinner spinnerCity;
	private Spinner spinnerRegion;
	private TextView txtInfo;
	private Hashtable<String, Hashtable<String, String[]>> hashtable;
	private String[] arrProvince, arrCity, arrRegion;
	private String province, city, region;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		comparator = new ChinaAlphabetComparator();
		hashtable = ChinaCityUtil.initChinaCitysHashtable();
		arrProvince = ChinaCityUtil.findAreaStringArr(hashtable, ChinaCityUtil.TYPE_PROVINCE);
		ArrayAdapter<String> adapterProvince = getArrayAdapter(arrProvince);
		spinnerProvince = (Spinner) findViewById(R.id.spinnerProvince);
		spinnerProvince.setAdapter(adapterProvince);
		spinnerProvince.setOnItemSelectedListener(this);
		spinnerCity = (Spinner) findViewById(R.id.spinnerCity);
		spinnerCity.setOnItemSelectedListener(this);
		spinnerRegion = (Spinner) findViewById(R.id.spinnerRegion);
		spinnerRegion.setOnItemSelectedListener(this);
		txtInfo = (TextView) findViewById(R.id.txtInfo);
	}

	private ArrayAdapter<String> getArrayAdapter(String[] arr) {
		ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
				android.R.layout.simple_spinner_item, arr);
		adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
		adapter.sort(comparator);
		return adapter;
	}

	private void modifyCity(String province) {
		arrCity = ChinaCityUtil.findAreaStringArr(hashtable, ChinaCityUtil.TYPE_CITY, province);
		ArrayAdapter<String> adapterCity = getArrayAdapter(arrCity);
		spinnerCity.setAdapter(adapterCity);
	}

	private void modifyRegion(String province, String city) {
		arrRegion = ChinaCityUtil.findAreaStringArr(hashtable, ChinaCityUtil.TYPE_REGION, province,
				city);
		ArrayAdapter<String> adapterRegion = getArrayAdapter(arrRegion);
		spinnerRegion.setAdapter(adapterRegion);
	}

	@Override
	public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
		if (parent == spinnerProvince) {
			province = arrProvince[position];
			modifyCity(province);
		} else if (parent == spinnerCity) {
			city = arrCity[position];
			modifyRegion(province, city);
		} else if (parent == spinnerRegion) {
			region = arrRegion[position];
			txtInfo.setText(province + " " + city + " " + region);
		}
	}

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

	}
}


ChinaAlphabetComparator.java

package lab.sodino.chinacity;

import java.text.CollationKey;
import java.text.Collator;
import java.text.RuleBasedCollator;
import java.util.Comparator;

/**
 * @author Sodino E-mail:sodinoopen@hotmail.com
 * @version Time:2011-8-20 下午08:41:25
 */
public class ChinaAlphabetComparator implements Comparator<String> {

	private RuleBasedCollator collator;

	public ChinaAlphabetComparator() {
		collator = (RuleBasedCollator) Collator.getInstance(java.util.Locale.CHINA);
	}

	@Override
	public int compare(String obj1, String obj2) {
		obj1 = obj1.replace("重庆", "崇庆");
		obj2 = obj2.replace("重庆", "崇庆");
		CollationKey c1 = collator.getCollationKey(obj1);
		CollationKey c2 = collator.getCollationKey(obj2);
		// When sorting a list of Strings however, it is generally necessary to
		// compare each String multiple times. In this case, CollationKeys
		// provide better performance. The CollationKey class converts a String
		// to a series of bits that can be compared bitwise against other
		// CollationKeys. A CollationKey is created by a Collator object for a
		// given String.
		return c1.compareTo(c2);
		// return collator.compare(c1.getSourceString(), c2.getSourceString());
	}
}

ChinaCityUtil.java

package lab.sodino.chinacity;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

/**
 * @author Sodino E-mail:sodinoopen@hotmail.com
 * @version Time:2011-8-20 下午08:41:25
 */
public class ChinaCityUtil {
	public static final String CHINA = "中国";
	public static final int TYPE_PROVINCE = 1;
	public static final int TYPE_CITY = 2;
	public static final int TYPE_REGION = 3;

	public static Hashtable<String, Hashtable<String, String[]>> initChinaCitysHashtable() {
		Hashtable<String, Hashtable<String, String[]>> tmpProvince = new Hashtable<String, Hashtable<String, String[]>>();
		// 从小地区开始构建
		Hashtable<String, String[]> tmpCity = null;
		// 北京市
		tmpCity = new Hashtable<String, String[]>();
		tmpCity.put("北京市", new String[] { "昌平区", "朝阳区", "崇文区", "大兴区", "东城区", "房山区", "丰台区", "海淀区",
				"怀柔区", "门头沟", "
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值