Android ListView三级联动,实现自定义地址选择器

释放双眼,带上耳机,听听看~!

 

说到地址选择器,好多小伙伴第一印象就是——wheelView~这玩意确实挺好用的^(* ̄(oo) ̄)^!

然而悲剧的故事发生了,傲娇的老板不喜欢wheelView那种选中条不动的效果 ~(⊙o⊙)!
好吧,其实是老板不知道从哪个忘记名字的App看到这种效果,然后坚持要把地址选择器搞成这样。话不多说,先上图:
这里写图片描述
眼尖的小伙伴,应该一眼就看出了,没错,就只是3个listView拼起来的效果。说到联动效果,即拿到listView1中item对应的String,去获取listView数据,把listView的String当成key,获取listView2对应的value(String[])。拿ListView2中item的String,获取ListView2的value(String[])。
已经有思路了,我们第一件事就是让后台给我们来份全国省市区的json文件。然后解析文件,拿到全国的地址数据。

/**
* 所有省
*/
private String[] mProvinceDatas;
/**
* key - 省 value - 市s
*/
private Map<String, String[]> mCitisDatasMap = new HashMap<String, String[]>();
/**
* key - 市 values - 区s
*/
private Map<String, String[]> mAreaDatasMap = new HashMap<String, String[]>();

解析数据:

 /**
* 解析整个Json对象,完成后释放Json对象的内存
*/
private void initDatas()
{
try
{
JSONArray jsonArray = mJsonObj.getJSONArray("citylist");
mProvinceDatas = new String[jsonArray.length()];
for (int i = 0; i < jsonArray.length(); i++)
{
JSONObject jsonP = jsonArray.getJSONObject(i);// 每个省的json对象
String province = jsonP.getString("p");// 省名字
mProvinceDatas[i] = province;
JSONArray jsonCs = null;
try
{
/**
* Throws JSONException if the mapping doesn't exist or is
* not a JSONArray.
*/
jsonCs = jsonP.getJSONArray("c");
} catch (Exception e1)
{
continue;
}
String[] mCitiesDatas = new String[jsonCs.length()];
for (int j = 0; j < jsonCs.length(); j++)
{
JSONObject jsonCity = jsonCs.getJSONObject(j);
String city = jsonCity.getString("n");// 市名字
mCitiesDatas[j] = city;
JSONArray jsonAreas = null;
try
{
/**
* Throws JSONException if the mapping doesn't exist or
* is not a JSONArray.
*/
jsonAreas = jsonCity.getJSONArray("a");
} catch (Exception e)
{
continue;
}
String[] mAreasDatas = new String[jsonAreas.length()];// 当前市的所有区
for (int k = 0; k < jsonAreas.length(); k++)
{
String area = jsonAreas.getJSONObject(k).getString("s");// 区域的名称
mAreasDatas[k] = area;
}
mAreaDatasMap.put(city, mAreasDatas);
}
mCitisDatasMap.put(province, mCitiesDatas);
}
} catch (JSONException e)
{
e.printStackTrace();
}
mJsonObj = null;
}
/**
* 从assert文件夹中读取省市区的json文件,然后转化为json对象
*/
private void initJsonData()
{
try
{
StringBuffer sb = new StringBuffer();
InputStream is = context.getAssets().open("city.json");
int len = -1;
byte[] buf = new byte[1024];
while ((len = is.read(buf)) != -1)
{
sb.append(new String(buf, 0, len, "utf-8"));
}
is.close();
mJsonObj = new JSONObject(sb.toString());
} catch (IOException e)
{
e.printStackTrace();
} catch (JSONException e)
{
e.printStackTrace();
}
}

一开始showDialog的时候,我们需要给三个listView设置默认值:

private void selectCityDefult() {
provincePosition=0;
mAdapter1.setSelectedPosition(0);
mAdapter1.notifyDataSetInvalidated();
citys=mCitisDatasMap.get(mProvinceDatas[0]);
cityPosition=0;
mAdapter2=new TextAdapter(citys,context);
mAdapter2.setSelectedPosition(0);
listView2.setAdapter(mAdapter2);
listView2.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
cityPosition = position;
mAdapter2.setSelectedPosition(cityPosition);
mAdapter2.notifyDataSetInvalidated();
areas = mAreaDatasMap.get(citys[cityPosition]);
mAdapter3 = new TextAdapter(areas,context);
listView3.setAdapter(mAdapter3);
}
});
areasPosition=0;
areas =mAreaDatasMap.get(citys[0]);
mAdapter3 =new TextAdapter(areas,context);
mAdapter3.setSelectedPosition(0);
listView3.setAdapter(mAdapter3);
listView3.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent,
View view, int position, long id) {
areasPosition=position;
province=mProvinceDatas[position];
mAdapter3.setSelectedPosition(areasPosition);
mAdapter3.notifyDataSetInvalidated();
//position为最后一个数组的position
//                Toast.makeText(context,
//                        "provincePosition=" + provincePosition + "cityPosition=" + cityPosition + "areasPosition=" + areasPosition,
//                        Toast.LENGTH_LONG).show();
province=mProvinceDatas[provincePosition];
city =mCitisDatasMap.get(province)[cityPosition];
area =mAreaDatasMap.get(city)[areasPosition];
textBack.textback(province,city,area);
}
});
}

有人可能会问了,你为什么不把listView1的setOnItemclick也放进selectCityDefult()去, 嗯哼,我觉得默认的概念是选中,ItemClick不应该包括进去,至于listView2和listView3的ItemClick是因为逻辑需要才放进去的~(⊙o⊙)!
好吧,有些人只想看怎么用,自定义dialog的完整代码

import android.app.AlertDialog;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
/**
* Created by KID on 2016/12/20.
*/
public class XsAddressDialog extends AlertDialog{
private Context context;
/**
* 把全国的省市区的信息以json的格式保存,解析完成后赋值为null
*/
private JSONObject mJsonObj;
//省的listView
private MyListView listView1;
private TextAdapter mAdapter1;
//市的listView
private MyListView listView2;
private TextAdapter mAdapter2;
//区的listView
private MyListView listView3;
private TextAdapter mAdapter3;
/**
* 所有省
*/
private String[] mProvinceDatas;
/**
* key - 省 value - 市s
*/
private Map<String, String[]> mCitisDatasMap = new HashMap<String, String[]>();
/**
* key - 市 values - 区s
*/
private Map<String, String[]> mAreaDatasMap = new HashMap<String, String[]>();
//当前的citys
private String []citys;
//当前的areas
private String []areas;
//当前省市区的选中位置
public int provincePosition;
public int cityPosition;
public int areasPosition;
//最终选中的省,市,区
private String province;
private String city;
private String area;
public XsAddressDialog(Context context, int themeResId) {
super(context, R.style.mycustom_dialog);
this.context = context;
}
private TextBack textBack;
public interface TextBack{
void textback(String province, String city, String area);
}
public void setTextBackListener(TextBack textBack) {
this.textBack=textBack;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
init();
}
private void init() {
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.dialog_address, null);
ViewGroup.LayoutParams layoutParams =new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
setContentView(view,layoutParams);
//-------------------------------------------------------------------
initJsonData();
initDatas();
listView1= (MyListView) view.findViewById(R.id.listview1);
listView2=(MyListView) view.findViewById(R.id.listview2);
listView3=(MyListView) view.findViewById(R.id.listview3);
mAdapter1=new TextAdapter(mProvinceDatas,context);
listView1.setAdapter(mAdapter1);
//设置city的默认值
selectCityDefult();
listView1.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
provincePosition = position;
mAdapter1.setSelectedPosition(provincePosition);
mAdapter1.notifyDataSetInvalidated();
citys = mCitisDatasMap.get(mProvinceDatas[provincePosition]);
mAdapter2 = new TextAdapter(citys, context);
listView2.setAdapter(mAdapter2);
mAdapter2.setSelectedPosition(0);
listView2.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
cityPosition = position;
mAdapter2.setSelectedPosition(cityPosition);
mAdapter2.notifyDataSetInvalidated();
areas = mAreaDatasMap.get(citys[cityPosition]);
mAdapter3 = new TextAdapter(areas, context);
mAdapter3.setSelectedPosition(0);
listView3.setAdapter(mAdapter3);
}
});
areas = mAreaDatasMap.get(citys[0]);
mAdapter3 = new TextAdapter(areas, context);
mAdapter3.setSelectedPosition(0);
listView3.setAdapter(mAdapter3);
}
});
}
private void selectCityDefult() {
//-------------------------------------------------------------------
provincePosition=0;
mAdapter1.setSelectedPosition(0);
mAdapter1.notifyDataSetInvalidated();
citys=mCitisDatasMap.get(mProvinceDatas[0]);
cityPosition=0;
mAdapter2=new TextAdapter(citys,context);
mAdapter2.setSelectedPosition(0);
listView2.setAdapter(mAdapter2);
listView2.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
cityPosition = position;
mAdapter2.setSelectedPosition(cityPosition);
mAdapter2.notifyDataSetInvalidated();
areas = mAreaDatasMap.get(citys[cityPosition]);
mAdapter3 = new TextAdapter(areas,context);
listView3.setAdapter(mAdapter3);
}
});
areasPosition=0;
areas =mAreaDatasMap.get(citys[0]);
mAdapter3 =new TextAdapter(areas,context);
mAdapter3.setSelectedPosition(0);
listView3.setAdapter(mAdapter3);
listView3.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent,
View view, int position, long id) {
areasPosition=position;
province=mProvinceDatas[position];
mAdapter3.setSelectedPosition(areasPosition);
mAdapter3.notifyDataSetInvalidated();
//position为最后一个数组的position
//                Toast.makeText(context,
//                        "provincePosition=" + provincePosition + "cityPosition=" + cityPosition + "areasPosition=" + areasPosition,
//                        Toast.LENGTH_LONG).show();
province=mProvinceDatas[provincePosition];
city =mCitisDatasMap.get(province)[cityPosition];
area =mAreaDatasMap.get(city)[areasPosition];
textBack.textback(province,city,area);
}
});
}
/**
* 解析整个Json对象,完成后释放Json对象的内存
*/
private void initDatas()
{
try
{
JSONArray jsonArray = mJsonObj.getJSONArray("citylist");
mProvinceDatas = new String[jsonArray.length()];
for (int i = 0; i < jsonArray.length(); i++)
{
JSONObject jsonP = jsonArray.getJSONObject(i);// 每个省的json对象
String province = jsonP.getString("p");// 省名字
mProvinceDatas[i] = province;
JSONArray jsonCs = null;
try
{
/**
* Throws JSONException if the mapping doesn't exist or is
* not a JSONArray.
*/
jsonCs = jsonP.getJSONArray("c");
} catch (Exception e1)
{
continue;
}
String[] mCitiesDatas = new String[jsonCs.length()];
for (int j = 0; j < jsonCs.length(); j++)
{
JSONObject jsonCity = jsonCs.getJSONObject(j);
String city = jsonCity.getString("n");// 市名字
mCitiesDatas[j] = city;
JSONArray jsonAreas = null;
try
{
/**
* Throws JSONException if the mapping doesn't exist or
* is not a JSONArray.
*/
jsonAreas = jsonCity.getJSONArray("a");
} catch (Exception e)
{
continue;
}
String[] mAreasDatas = new String[jsonAreas.length()];// 当前市的所有区
for (int k = 0; k < jsonAreas.length(); k++)
{
String area = jsonAreas.getJSONObject(k).getString("s");// 区域的名称
mAreasDatas[k] = area;
}
mAreaDatasMap.put(city, mAreasDatas);
}
mCitisDatasMap.put(province, mCitiesDatas);
}
} catch (JSONException e)
{
e.printStackTrace();
}
mJsonObj = null;
}
/**
* 从assert文件夹中读取省市区的json文件,然后转化为json对象
*/
private void initJsonData()
{
try
{
StringBuffer sb = new StringBuffer();
InputStream is = context.getAssets().open("city.json");
int len = -1;
byte[] buf = new byte[1024];
while ((len = is.read(buf)) != -1)
{
sb.append(new String(buf, 0, len, "utf-8"));
}
is.close();
mJsonObj = new JSONObject(sb.toString());
} catch (IOException e)
{
e.printStackTrace();
} catch (JSONException e)
{
e.printStackTrace();
}
}
}

使用Activity的代码

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Gravity;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private Button button;
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button) findViewById(R.id.btn_show_address_picker);
textView = (TextView) findViewById(R.id.tv_result);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showDialog();
}
});
}
private void showDialog() {
final XsAddressDialog dialog = new XsAddressDialog(this,R.style.mycustom_dialog);
dialog.show();
dialog.setCancelable(true);
Window win = dialog.getWindow();
win.getDecorView().setPadding(0, 0, 0, 0);
WindowManager.LayoutParams lp = win.getAttributes();
// 设置弹出框的宽高
lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
lp.height = 500;
// 设置弹出框的位置
win.setGravity(Gravity.BOTTOM);
win.setAttributes(lp);
dialog.setTextBackListener(new XsAddressDialog.TextBack() {
@Override
public void textback(String province, String city, String area) {
textView.setText("选中地址是:     "+province+"---"+city+"---"+area);
dialog.dismiss();
}
});
}
}

在setTextBackListener里获取省市区就行了。
代码链接:http://download.csdn.net/detail/qq_31390699/9716725

为TA充电
共{{data.count}}人
人已赞赏
Android文章

Android开发检测手机是否安装了微信或者支付宝

2021-4-21 18:24:24

Android文章

Android开发中登录注册界面的框架实现(android studio)

2021-5-6 11:32:08

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索