Android ListView三级联动,实现自定义地址选择器
来源:互联网 发布:ubuntu查看当前目录 编辑:程序博客网 时间:2024/05/29 19:10
说到地址选择器,好多小伙伴第一印象就是——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
- Android ListView三级联动,实现自定义地址选择器
- Android 地址选择器,实现省市区三级联动
- Android 地址选择器,实现省市区三级联动
- 自定义三级联动地址选择器
- 使用listview实现简单的三级地址联动选择器
- Android 日期选择器,实现年月日三级联动
- Android 日期选择器,实现年月日三级联动
- Android仿iOS实现三级联动选择器
- 三级联动的地址选择器
- 使用pickerview实现(省市区)地址选择器的三级联动
- weex 实现仿ios 三级联动地址选择器
- Android城市三级联动选择器
- 微信小程序三级联动地址选择器
- 一个三级联动的地址选择器
- Android时间选择器(三级联动修改年月日)
- 安卓选择器类库,包括日期选择器、时间选择器、单项选择器、数字选择器、二三级联动选择器、省市区地址选择器、颜色选择器、文件目录选择器等,可自定义顶部及底部界面,可自定义窗口动画
- android省市区三级联动实现
- android 三级联动,二级联动,省市县选择器
- A+B
- PHP开发工具及服务器
- sql sever 求阶乘的案例
- 集合的操作(员工类 第三篇)
- Http session
- Android ListView三级联动,实现自定义地址选择器
- 【PHP】静态缓存简单应用
- ubuntu使用NAT实现局域网的网络共享
- Oracle_sql_(7)
- 用 Flask 来写个轻博客 (28) — 使用 Flask-Assets 压缩 CSS/JS 提升网页加载速度
- 从零开始做远控 第三篇
- mysql索引失效统计
- 11111111111
- Struts2+Spring4+Hibernate4整合系列--(四)StepByStep4