今天我們來(lái)說(shuō)一個(gè)非常好用的框架PickerView,來(lái)完成地址選擇器的功能。還是老原則不好用,不推薦。先上個(gè)效果圖。
1.首先我們來(lái)做準(zhǔn)備工作。
添加依賴(lài)
compile 'com.contrarywind:Android-PickerView:3.2.5'
//里面有用到gson,如果原來(lái)項(xiàng)目中有無(wú)需添加gson
compile 'com.google.code.gson:gson:2.3.1'
添加gson的混淆
##---------------Begin: proguard configuration for Gson ----------
# Gson 代碼混淆
-keepattributes Signature
-keepattributes *Annotation*
-keep class sun.misc.Unsafe { *; }
-keep class com.daiba.wsjr.bean.** { *; }
##---------------End: proguard configuration for Gson ----------
在main文件夾下創(chuàng)建assets的文件夾用于放保存地址數(shù)據(jù)的json文件city.json。city.json文件里的內(nèi)容會(huì)附在最后。效果如下。
這里寫(xiě)圖片描述
然后免費(fèi)送一個(gè)將json文件里的數(shù)據(jù)轉(zhuǎn)換成json字符串的類(lèi)。需要貼在項(xiàng)目里的偶。
public class GetJsonDataUtil {
public String getJson(Context context, String fileName) {
StringBuilder stringBuilder = new StringBuilder();
try {
AssetManager assetManager = context.getAssets();
BufferedReader bf = new BufferedReader(new InputStreamReader(
assetManager.open(fileName)));
String line;
while ((line = bf.readLine()) != null) {
stringBuilder.append(line);
}
} catch (IOException e) {
e.printStackTrace();
}
return stringBuilder.toString();
}
}
最后在貼一個(gè)承載城市數(shù)據(jù)的類(lèi)。
public class CityBean implements IPickerViewData {
/**
* province : 北京
* city_list : ["北京"]
*/
private String province;
private List<String> city_list;
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public List<String> getCity_list() {
return city_list;
}
public void setCity_list(List<String> city_list) {
this.city_list = city_list;
}
@Override
public String getPickerViewText() {
return this.province;
}
}
然后我們切入正題,先做好聲明,省的你們粘完代碼報(bào)錯(cuò)了,又說(shuō)我都是按你的寫(xiě)的啊怎么報(bào)錯(cuò)呢?┭┮﹏┭┮
private ArrayList<CityBean> options1Items = new ArrayList<>();
private ArrayList<ArrayList<String>> options2Items = new ArrayList<>();
private ArrayList<ArrayList<ArrayList<String>>> options3Items = new ArrayList<>();
private ArrayList<String> bankNameList = new ArrayList<>();
private Thread thread;
private static final int MSG_LOAD_DATA = 0x0001;
private static final int MSG_LOAD_SUCCESS = 0x0002;
private static final int MSG_LOAD_FAILED = 0x0003;
private boolean isLoaded = false;
private String province;
private String city;
private TextView bank_addr;
因?yàn)槲覀円虞djson文件中的數(shù)據(jù),這屬于耗時(shí)操作需要一個(gè)子線(xiàn)程,數(shù)據(jù)加載完畢才能讓選擇器展示數(shù)據(jù)。這里免我們用到了Handle解決這個(gè)問(wèn)題。
(往方法區(qū)粘就行)
//判斷地址數(shù)據(jù)是否獲取成功
private Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_LOAD_DATA:
if (thread==null){//如果已創(chuàng)建就不再重新創(chuàng)建子線(xiàn)程了
Log.i("addr","地址數(shù)據(jù)開(kāi)始解析");
thread = new Thread(new Runnable() {
@Override
public void run() {
// 寫(xiě)子線(xiàn)程中的操作,解析省市區(qū)數(shù)據(jù)
initJsonData();
}
});
thread.start();
}
break;
case MSG_LOAD_SUCCESS:
Log.i("addr","地址數(shù)據(jù)獲取成功");
isLoaded = true;
break;
case MSG_LOAD_FAILED:
Log.i("addr","地址數(shù)據(jù)獲取失敗");
break;
}
}
};
下面的是剛才用到的解析數(shù)據(jù)的工具類(lèi)
private void initJsonData() {//解析數(shù)據(jù)
/**
* 注意:assets 目錄下的Json文件僅供參考,實(shí)際使用可自行替換文件
* 關(guān)鍵邏輯在于循環(huán)體
*
* */
String CityData = new GetJsonDataUtil().getJson(this,"city.json");//獲取assets目錄下的json文件數(shù)據(jù)
ArrayList<CityBean> jsonBean = parseData(CityData);//用Gson 轉(zhuǎn)成實(shí)體
/**
* 添加省份數(shù)據(jù)
*
* 注意:如果是添加的JavaBean實(shí)體,則實(shí)體類(lèi)需要實(shí)現(xiàn) IPickerViewData 接口,
* PickerView會(huì)通過(guò)getPickerViewText方法獲取字符串顯示出來(lái)。
*/
options1Items = jsonBean;
for (int i=0;i<jsonBean.size();i++){//遍歷省份
ArrayList<String> CityList = new ArrayList<>();//該省的城市列表(第二級(jí))
ArrayList<ArrayList<String>> Province_AreaList = new ArrayList<>();//該省的所有地區(qū)列表(第三極)
for (int c=0; c<jsonBean.get(i).getCity_list().size(); c++){//遍歷該省份的所有城市
String CityName = jsonBean.get(i).getCity_list().get(c);
CityList.add(CityName);//添加城市
}
/**
* 添加城市數(shù)據(jù)
*/
options2Items.add(CityList);
}
mHandler.sendEmptyMessage(MSG_LOAD_SUCCESS);
}
public ArrayList<CityBean> parseData(String result) {//Gson 解析
ArrayList<CityBean> detail = new ArrayList<>();
try {
JSONArray data = new JSONArray(result);
Gson gson = new Gson();
for (int i = 0; i < data.length(); i++) {
CityBean entity = gson.fromJson(data.optJSONObject(i).toString(), CityBean.class);
detail.add(entity);
}
} catch (Exception e) {
e.printStackTrace();
mHandler.sendEmptyMessage(MSG_LOAD_FAILED);
}
return detail;
}
最后一個(gè)是彈出地址選擇器的類(lèi)
private void ShowPickerView() {// 彈出地址選擇器
OptionsPickerView pvOptions = new OptionsPickerView.Builder(this, new OptionsPickerView.OnOptionsSelectListener() {
@Override
public void onOptionsSelect(int options1, int options2, int options3, View v) {
//返回的分別是三個(gè)級(jí)別的選中位置
province = options1Items.get(options1).getPickerViewText();
city = options2Items.get(options1).get(options2);
// + options3Items.get(options1).get(options2).get(options3);
bank_addr.setText(province+city);
}
})
.setDividerColor(Color.BLACK)
.setTextColorCenter(Color.BLACK) //設(shè)置選中項(xiàng)文字顏色
.setContentTextSize(20)
.setOutSideCancelable(false)// default is true
.build();
pvOptions.setPicker(options1Items, options2Items);//二級(jí)選擇器(市區(qū))
//pvOptions.setPicker(options1Items, options2Items, options3Items);//三級(jí)選擇器
pvOptions.show();
}
然后我們?cè)趏nCreate方法里啟動(dòng)剛才的handle線(xiàn)程
mHandler.sendEmptyMessage(MSG_LOAD_DATA);
大功告成。
city.json的文件忘記給大家了放在下面了,把他粘貼在文本文檔里把文本文檔的后綴名改成.json就變成json文件了。
city.json
[
{
"province": "北京",
"city_list": [
"北京"
]
},
{
"province": "天津",
"city_list": [
"天津"
]
},
{
"province": "河北",
"city_list": [
"保定",
"唐山",
"廊坊",
"張家口",
"承德",
"滄州",
"石家莊",
"秦皇島",
"衡水",
"邢臺(tái)",
"邯鄲"
]
},
{
"province": "山西",
"city_list": [
"臨汾",
"呂梁",
"大同",
"太原",
"忻州",
"晉中",
"晉城",
"朔州",
"運(yùn)城",
"長(zhǎng)治",
"陽(yáng)泉"
]
},
{
"province": "內(nèi)蒙古",
"city_list": [
"烏蘭察布",
"烏海",
"興安",
"包頭",
"呼倫貝爾",
"呼和浩特",
"巴彥淖爾",
"赤峰",
"通遼",
"鄂爾多斯",
"錫林郭勒",
"阿拉善"
]
},
{
"province": "遼寧",
"city_list": [
"丹東",
"大連",
"撫順",
"朝陽(yáng)",
"本溪",
"沈陽(yáng)",
"盤(pán)錦",
"營(yíng)口",
"葫蘆島",
"遼陽(yáng)",
"鐵嶺",
"錦州",
"阜新",
"鞍山"
]
},
{
"province": "吉林",
"city_list": [
"吉林",
"四平",
"延邊",
"松原",
"白城",
"白山",
"遼源",
"通化",
"長(zhǎng)春"
]
},
{
"province": "黑龍江",
"city_list": [
"七臺(tái)河",
"伊春",
"佳木斯",
"雙鴨山",
"哈爾濱",
"大興安嶺",
"大慶",
"牡丹江",
"綏化",
"雞西",
"鶴崗",
"黑河",
"齊齊哈爾"
]
},
{
"province": "上海",
"city_list": [
"上海"
]
},
{
"province": "江蘇",
"city_list": [
"南京",
"南通",
"宿遷",
"常州",
"徐州",
"揚(yáng)州",
"無(wú)錫",
"泰州",
"淮安",
"鹽城",
"蘇州",
"連云港",
"鎮(zhèn)江"
]
},
{
"province": "浙江",
"city_list": [
"麗水",
"臺(tái)州",
"嘉興",
"寧波",
"杭州",
"溫州",
"湖州",
"紹興",
"舟山",
"衢州",
"金華"
]
},
{
"province": "安徽",
"city_list": [
"亳州",
"六安",
"合肥",
"安慶",
"宣城",
"宿州",
"池州",
"淮北",
"淮南",
"滁州",
"蕪湖",
"蚌埠",
"銅陵",
"阜陽(yáng)",
"馬鞍山",
"黃山"
]
},
{
"province": "福建",
"city_list": [
"三明",
"南平",
"廈門(mén)",
"寧德",
"泉州",
"漳州",
"福州",
"莆田",
"龍巖"
]
},
{
"province": "江西",
"city_list": [
"上饒",
"九江",
"南昌",
"吉安",
"宜春",
"撫州",
"新余",
"景德鎮(zhèn)",
"萍鄉(xiāng)",
"贛州",
"鷹潭"
]
},
{
"province": "山東",
"city_list": [
"東營(yíng)",
"臨沂",
"威海",
"德州",
"日照",
"棗莊",
"泰安",
"濟(jì)南",
"濟(jì)寧",
"淄博",
"濱州",
"濰坊",
"煙臺(tái)",
"聊城",
"萊蕪",
"菏澤",
"青島"
]
},
{
"province": "河南",
"city_list": [
"三門(mén)峽",
"信陽(yáng)",
"南陽(yáng)",
"周口",
"商丘",
"安陽(yáng)",
"平頂山",
"開(kāi)封",
"新鄉(xiāng)",
"洛陽(yáng)",
"漯河",
"濮陽(yáng)",
"焦作",
"省直轄",
"許昌",
"鄭州",
"駐馬店",
"鶴壁"
]
},
{
"province": "湖北",
"city_list": [
"十堰",
"咸寧",
"孝感",
"宜昌",
"恩施",
"武漢",
"省直轄",
"荊州",
"荊門(mén)",
"襄陽(yáng)",
"鄂州",
"隨州",
"黃岡",
"黃石"
]
},
{
"province": "湖南",
"city_list": [
"婁底",
"岳陽(yáng)",
"常德",
"張家界",
"懷化",
"株洲",
"永州",
"湘潭",
"湘西",
"益陽(yáng)",
"衡陽(yáng)",
"邵陽(yáng)",
"郴州",
"長(zhǎng)沙"
]
},
{
"province": "廣東",
"city_list": [
"東莞",
"中山",
"云浮",
"佛山",
"廣州",
"惠州",
"揭陽(yáng)",
"梅州",
"汕頭",
"汕尾",
"江門(mén)",
"河源",
"深圳",
"清遠(yuǎn)",
"湛江",
"潮州",
"珠海",
"肇慶",
"茂名",
"陽(yáng)江",
"韶關(guān)"
]
},
{
"province": "廣西",
"city_list": [
"北海",
"南寧",
"崇左",
"來(lái)賓",
"柳州",
"桂林",
"梧州",
"河池",
"玉林",
"百色",
"貴港",
"賀州",
"欽州",
"防城港"
]
},
{
"province": "海南",
"city_list": [
"三亞",
"???,
"省直轄"
]
},
{
"province": "重慶",
"city_list": [
"重慶"
]
},
{
"province": "四川",
"city_list": [
"樂(lè)山",
"內(nèi)江",
"涼山",
"南充",
"宜賓",
"巴中",
"廣元",
"廣安",
"德陽(yáng)",
"成都",
"攀枝花",
"瀘州",
"甘孜",
"眉山",
"綿陽(yáng)",
"自貢",
"資陽(yáng)",
"達(dá)州",
"遂寧",
"阿壩",
"雅安"
]
},
{
"province": "貴州",
"city_list": [
"六盤(pán)水",
"安順",
"畢節(jié)",
"貴陽(yáng)",
"遵義",
"銅仁",
"黔東南",
"黔南",
"黔西南"
]
},
{
"province": "云南",
"city_list": [
"臨滄",
"麗江",
"保山",
"大理",
"德宏",
"怒江",
"文山",
"昆明",
"昭通",
"普洱",
"曲靖",
"楚雄",
"玉溪",
"紅河",
"西雙版納",
"迪慶"
]
},
{
"province": "西藏",
"city_list": [
"山南",
"拉薩",
"日喀則",
"昌都",
"林芝",
"那曲",
"阿里"
]
},
{
"province": "陜西",
"city_list": [
"咸陽(yáng)",
"商洛",
"安康",
"寶雞",
"延安",
"榆林",
"漢中",
"渭南",
"西安",
"銅川"
]
},
{
"province": "甘肅",
"city_list": [
"臨夏",
"蘭州",
"嘉峪關(guān)",
"天水",
"定西",
"平?jīng)?,
"慶陽(yáng)",
"張掖",
"武威",
"甘南",
"白銀",
"酒泉",
"金昌",
"隴南"
]
},
{
"province": "青海",
"city_list": [
"果洛",
"海東",
"海北",
"海南",
"海西",
"玉樹(shù)",
"西寧",
"黃南"
]
},
{
"province": "寧夏",
"city_list": [
"中衛(wèi)",
"吳忠",
"固原",
"石嘴山",
"銀川"
]
},
{
"province": "新疆",
"city_list": [
"烏魯木齊",
"伊犁",
"克孜勒蘇",
"克拉瑪依",
"區(qū)直轄",
"博爾塔拉",
"吐魯番",
"和田",
"哈密",
"喀什",
"塔城",
"巴音郭楞",
"昌吉",
"阿克蘇",
"阿勒泰"
]
}
]