Android ListView三级联动,实现自定义地址选择器
2016-12-20 16:45
956 查看
说到地址选择器,好多小伙伴第一印象就是——wheelView~这玩意确实挺好用的^(* ̄(oo) ̄)^!
然而悲剧的故事发生了,傲娇的老板不喜欢wheelView那种选中条不动的效果 ~(⊙o⊙)!
好吧,其实是老板不知道从哪个忘记名字的App看到这种效果,然后坚持要把地址选择器搞成这样。话不多说,先上图:
眼尖的小伙伴,应该一眼就看出了,没错,就只是3个listView拼起来的效果。说到联动效果,即拿到listView1中item对应的String,去获取listView数据,把listView的String当成key,获取listView2对应的value(String[])。拿ListView2中item的String,获取ListView2的value(String[])。
已经有思路了,我们第一件事就是让后台给我们来份全国省市区的json文件。然后解析文件,拿到全国的地址数据。
解析数据:
一开始showDialog的时候,我们需要给三个listView设置默认值:
有人可能会问了,你为什么不把listView1的setOnItemclick也放进selectCityDefult()去, 嗯哼,我觉得默认的概念是选中,ItemClick不应该包括进去,至于listView2和listView3的ItemClick是因为逻辑需要才放进去的~(⊙o⊙)!
好吧,有些人只想看怎么用,自定义dialog的完整代码
使用Activity的代码
在setTextBackListener里获取省市区就行了。
代码链接:http://download.csdn.net/detail/qq_31390699/9716725
然而悲剧的故事发生了,傲娇的老板不喜欢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
相关文章推荐
- 使用listview实现简单的三级地址联动选择器
- Android仿iOS实现三级联动选择器
- weex 实现仿ios 三级联动地址选择器
- Android 地址选择器,实现省市区三级联动
- Android实现三级联动下拉框 城市选择器(简单)
- 使用pickerview实现(省市区)地址选择器的三级联动
- Android 地址选择器,实现省市区三级联动
- 仿IOS特效(一)——Android 自定义View实现3D滚轮效果的城市联动选择器
- Android---自定义带CheckBox的ExpandableListView实现
- 实现自定义view(2):仿Android QQ多屏幕显示ListView的效果
- Android UI控件之Spinner实现省市区三级联动
- android自定义listview实现圆角
- android 自定义ScrollView实现反弹效果(以及解决和ListView之间的冲突) .
- Android中自定义Adapter实现ListView动态刷新进度条
- android开发——用GridView实现省市县三级联动
- ANDROID中自定义ADAPTER实现LISTVIEW动态刷新进度条
- android 联动listview 的一种不太健康的实现方式
- Android ListView 自定义用法(ListView 实现单选功能)
- android 自定义ScrollView实现反弹效果(以及解决和ListView之间的冲突)
- Android中自定义Adapter实现ListView动态刷新进度条