在安卓APP编写中经常需要对获取的数据进行排序显示,这就需要我们在获取到数据源后,对数据源进行处理。由于中文不能直接排序,需要借助汉语拼音,于是就有了引入第三方的架包,极大的方便了我们对数据的转换,下面来介绍下应该怎么运用,以及注意事项。
1.将第三方架包下载后导入到我们的项目中lib下,这里我使用的是Eclipse,用安卓studio的方法类似。
2.在代码中的实现,事例如下:
public class PinYinUtil {
/**
* 返回汉语拼音格式的内容
* "北京",返回"BEIJING"
* "单"
* @param name
* @return
*/
public static String getPinYin(String name){
String result="";
try {
//使用pinyin4将汉字转拼音步骤
//1)设定好拼音的格式
HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
format.setCaseType(HanyuPinyinCaseType.UPPERCASE);
format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
//2)调用一个静态方法按照第一步设定的格式进行转换
StringBuilder sb = new StringBuilder();
for(int i=0;i<name.length();i++){
//做汉字转拼音之前要做一个判断,看一下当前要转换的字符串是不是汉字,否则直接转换会报错
//例如:汉字中间带一些特殊字符,是不能够识别的
String string = name.substring(i,i+1);
//这里应用了正则表达式,对是否是汉字进行判断,汉字的Unicode编码范围为\u4E00-\u9FFF
if(string.matches("[\u4E00-\u9FFF]")){
//"DAN","SHAN"这里需要注意多音字的处理,这里暂且选择了数组中下标为零的那个汉语拼音
String[] pinyin = PinyinHelper.toHanyuPinyinStringArray(name.charAt(i), format);
sb.append(pinyin[0]);
}else{
sb.append(string);
}
}
result = sb.toString();
} catch (BadHanyuPinyinOutputFormatCombination e) {
e.printStackTrace();
}
return result;
}
}
这段代码中需要注意的一共有两点:
1.做汉字转拼音之前要做一个判断,否则如果数据中的汉字如果包含一些特殊符号等运行会报错。
2.注意正则表达式的写法,以及汉字在Unicode中的编码范围。
在activity的刷新方法中对转换后的汉字进行字典排序:
private void refresh() {
HttpUtil.getCities(new Listener<String>() {
@Override
public void onResponse(String arg0) {
Gson gson = new Gson();
CityBean cityBean = gson.fromJson(arg0, CityBean.class);
List<String> list = cityBean.getCities();
//原始服务器返回的内容中,包含"全国",将其去掉
list.remove("全国");
List<CitynameBean> citynames = new ArrayList<CitynameBean>();
//Log.d("TAG",list.toString());
for (int i = 0; i <list.size(); i++) {
String cityname = list.get(i);//“北京”
CitynameBean bean = new CitynameBean();
bean.setCityName(cityname);
bean.setPyName(PinYinUtil.getPinYin(cityname));
bean.setSortLetter(bean.getPyName().charAt(0));
citynames.add(bean);
}
//对citynames要按照城市名称的拼音进行字典顺序排序
Collections.sort(citynames, new Comparator<CitynameBean>() {
@Override
public int compare(CitynameBean lhs, CitynameBean rhs) {
return lhs.getPyName().compareTo(rhs.getPyName());
}
});
//适配器
adapter.addAll(citynames, true);
}
});
}
对排序后在搜索框中搜索排序是否显示的注意事项:
在设置适配器数据源时,首先做一个判断:
CitynameBean bean = getItem(position);
vh.tvSortLetter.setText(String.valueOf(bean.getSortLetter()));
vh.tvCityname.setText(bean.getCityName());
if(getPositionForSection(getSectionForPosition(position))==position){
vh.tvSortLetter.setVisibility(View.VISIBLE);
}else{
vh.tvSortLetter.setVisibility(View.GONE);
}
return convertView;
这个判断语句中的getPositionForSection(),以及getSectionForPosition(),在使用时,首先要让activity实现一个(implements) SectionIndexer接口,以及重写对应的方法:
@Override
public int getPositionForSection(int section) {
//参数中所代表的分组信息的起始位置是在哪儿
for(int i=0;i<getCount();i++){
CitynameBean bean = getItem(i);
if(bean.getSortLetter()==section){
return i;
}
}
return -1;
}
@Override
public int getSectionForPosition(int position) {
// 数据源中,第position位置的数据,应该是属于哪一个分组
CitynameBean bean = getItem(position);
return bean.getSortLetter();
}
@Override
public Object[] getSections() {
// TODO Auto-generated method stub
return null;
}