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

说到地址选择器,好多小伙伴第一印象就是——wheelView~这玩意确实挺好用的^(* ̄(oo) ̄)^!
然而悲剧的故事发生了,傲娇的老板不喜欢wheelView那种选中条不动的效果 ~(⊙o⊙)!
好吧,其实是老板不知道从哪个忘记名字的App看到这种效果,然后坚持要把地址选择器搞成这样。话不多说,先上图:
Android ListView三级联动,实现自定义地址选择器_第1张图片
眼尖的小伙伴,应该一眼就看出了,没错,就只是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 mCitisDatasMap = new HashMap();
    /**
     * key - 市 values - 区s
     */
    private Map mAreaDatasMap = new HashMap();

解析数据:

 /**
     * 解析整个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 mCitisDatasMap = new HashMap();
    /**
     * key - 市 values - 区s
     */
    private Map mAreaDatasMap = new HashMap();
    //当前的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,Demo)