重写popwindow,打造属于你的精美UI三级城市联动

本文简单讲解下城市的三级联动:

效果如下图:

简单的讲解下思路:重写popwindow,popwindow的布局如上图,最上面三个TextView,下面三个ListView,然后将你的城市数组遍历之后写入到ListView中。

重写的PopWindow源码如下:

package com.zzb.cityselect.view;

import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.view.View;
import android.widget.AdapterView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.PopupWindow;

import com.zzb.cityselect.R;
import com.zzb.cityselect.adapter.CityPopWindowAdapter;
import com.zzb.cityselect.constant.City;
import com.zzb.cityselect.entity.CityItemEntity;
import org.xutils.view.annotation.ViewInject;
import org.xutils.x;


/**
 * 作者: 张梓彬
 * 日期: 2017/5/25 0025
 * 时间: 下午 5:01
 * 描述: 重写PopupWindow弹出城市三级联动列表
 */

public class CityListViewPopWindow extends PopupWindow {
    private View view;
    private static final String TAG = "CityListViewPopWindow";
    private ViewHolder viewHolder;
    private CityPopWindowAdapter provinceAdapter;
    private CityPopWindowAdapter cityAdapter;
    private CityPopWindowAdapter countyAdapter;
    private int provincePosition = -1;
    private int cityPosition = -1;
    private int countryPosition = -1;
    private final OnCheckChangeListener mOnCheckChangeListener;


    public CityListViewPopWindow(Context context, OnCheckChangeListener mOnCheckChangeListener) {
        super(context);
        view = View.inflate(context, R.layout.pop_goods_pcd_listview, null);
        this.mOnCheckChangeListener = mOnCheckChangeListener;
        viewHolder = new ViewHolder(view);
        initProvince(context);
        setContentView(view);
        setWidth(LinearLayout.LayoutParams.WRAP_CONTENT);
        setHeight(LinearLayout.LayoutParams.WRAP_CONTENT);
        setFocusable(true);
        setTouchable(true);
        setOutsideTouchable(true);
        setBackgroundDrawable(new ColorDrawable());
        setOnDismissListener(new OnDismissListener() {
            @Override
            public void onDismiss() {
            }
        });
    }


    private CityItemEntity provinceItem;
    private CityItemEntity cityItem;
    private CityItemEntity countryItem;

    private void initProvince(Context context) {
        provinceAdapter = new CityPopWindowAdapter(context);
        cityAdapter = new CityPopWindowAdapter(context);
        countyAdapter = new CityPopWindowAdapter(context);
        for (int i = 0; i < City.province.length; i++) {
            String provinceName = City.province[i];
            CityItemEntity item = new CityItemEntity(provinceName);
            provinceAdapter.addDATA(item);
        }
        viewHolder.lvProvince.setAdapter(provinceAdapter);
        viewHolder.lvCity.setAdapter(cityAdapter);
        viewHolder.lvDistrict.setAdapter(countyAdapter);
        provinceAdapter.notifyDataSetChanged();
        cityAdapter.notifyDataSetChanged();
        countyAdapter.notifyDataSetChanged();

        //        viewHolder.lvProvince.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                if (mOnCheckChangeListener != null) {

                }
                //清空城市集合
                cityAdapter.removeAllDATA();
                countyAdapter.removeAllDATA();

                if (provincePosition != -1) {
                    provinceItem = (CityItemEntity) parent.getItemAtPosition(provincePosition);
                    provinceItem.isChoose = false;
                }
                provincePosition = position;
                provinceItem = (CityItemEntity) parent.getItemAtPosition(position);
                provinceItem.isChoose = true;
                if (mOnCheckChangeListener != null) {
                    mOnCheckChangeListener.setProvinceText(provinceItem.cityName);
                }

                provinceAdapter.notifyDataSetChanged();
                cityAdapter.notifyDataSetChanged();
                countyAdapter.notifyDataSetChanged();
                cityPosition = -1;//防止角标越界
                addCity(provincePosition);


            }
        });


        viewHolder.lvCity.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                if (mOnCheckChangeListener != null) {

                }
                countyAdapter.removeAllDATA();
                if (cityPosition != -1) {
                    cityItem = (CityItemEntity) parent.getItemAtPosition(cityPosition);
                    cityItem.isChoose = false;
                }
                cityPosition = position;
                cityItem = (CityItemEntity) parent.getItemAtPosition(position);
                cityItem.isChoose = true;
                if (mOnCheckChangeListener != null) {
                    mOnCheckChangeListener.setCityText(cityItem.cityName);

                }

                cityAdapter.notifyDataSetChanged();
                countryPosition = -1;
                if (position==0){
                    CityListViewPopWindow.this.dismiss();
                    mOnCheckChangeListener.setCityText(provinceItem.cityName);
                    provinceItem.isChoose = false;
                    cityAdapter.removeAllDATA();
                    countyAdapter.removeAllDATA();
                }

                addCountry(provincePosition, cityPosition);

            }
        });


        viewHolder.lvDistrict.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                if (mOnCheckChangeListener != null) {

                }
                if (countryPosition != -1) {
                    countryItem = (CityItemEntity) parent.getItemAtPosition(countryPosition);
                    countryItem.isChoose = false;
                }
                countryPosition = position;
                countryItem = (CityItemEntity) parent.getItemAtPosition(position);
                countryItem.isChoose = true;
                countyAdapter.notifyDataSetChanged();

                if (mOnCheckChangeListener != null) {
                    //设置地区
                    mOnCheckChangeListener.setDistrictText(cityItem.cityName + "-" + countryItem.cityName);
                    CityListViewPopWindow.this.dismiss();
                    provinceItem.isChoose = false;
                    cityAdapter.removeAllDATA();
                    countyAdapter.removeAllDATA();
                }

                if (position==0){
                    CityListViewPopWindow.this.dismiss();
                    mOnCheckChangeListener.setDistrictText(cityItem.cityName);
                    provinceItem.isChoose = false;
                    cityAdapter.removeAllDATA();
                    countyAdapter.removeAllDATA();
                }

                countyAdapter.notifyDataSetChanged();



            }
        });
    }

    private void addCity(final int provincePosition) {
        String[] cityName = {};
        for (int i = 0; i < City.city[provincePosition].length; i++) {
            cityName = City.city[provincePosition];
        }
        for (int i = 0; i < cityName.length; i++) {
            String city = cityName[i];
            CityItemEntity item = new CityItemEntity(city);
            cityAdapter.addDATA(item);
        }
        cityAdapter.notifyDataSetChanged();


    }

    private void addCountry(int provincePosition, int cityPosition) {
        String[] countryName = {};
        for (int i = 0; i < City.county[provincePosition][cityPosition].length; i++) {
            countryName = City.county[provincePosition][cityPosition];
        }


        for (int i = 0; i < countryName.length; i++) {
            String country = countryName[i];
            CityItemEntity item = new CityItemEntity(country);
            countyAdapter.addDATA(item);
        }
        countyAdapter.notifyDataSetChanged();

    }

    /**
     * 用来点击选择显示文本的回调
     */
    public interface OnCheckChangeListener {

        void setProvinceText(String text);

        void setCityText(String text);


        void setDistrictText(String text);


    }


    static class ViewHolder {
        @ViewInject(R.id.lv_province)
        ListView lvProvince;
        @ViewInject(R.id.lv_city)
        ListView lvCity;
        @ViewInject(R.id.lv_district)
        ListView lvDistrict;

        ViewHolder(View view) {
            x.view().inject(this, view);
        }
    }
}
其实之前早已写好了,存在项目中,这次只是拎出来,有些框架没有去掉,也就2框架,Xutils3和Autolayout,我嫌麻烦就没去掉了,直接整理出来了

点击下载源码




好的,实现这个功能,您需要使用 PopupWindow 和 ListView 一起来实现。以下是大致的实现步骤: 1. 创建一个布局文件,包含三个 ListView,分别用于展示省、市、县的列表项。 2. 在代码中,创建一个 PopupWindow 对象,并设置其宽度和高度。 3. 将布局文件加载到 PopupWindow 中,并设置其可以获得焦点和触摸事件。 4. 分别为三个 ListView 设置适配器,并初始化省级数据。 5. 为省级 ListView 设置点击事件,当点击一个省份时,根据其对应的城市数据更新城市列表,并将县级列表数据清空。 6. 为城市级 ListView 设置点击事件,当点击一个城市时,根据其对应的县级数据更新县级列表。 7. 点击县级列表中的某一项时,选定该项,并将选定的省、市、县数据返回给上层 Activity。 具体实现细节可以参考以下代码示例: ``` // 创建 PopupWindow 对象 PopupWindow popupWindow = new PopupWindow(context); // 加载布局文件 View contentView = LayoutInflater.from(context).inflate(R.layout.popupwindow_layout, null); popupWindow.setContentView(contentView); // 设置 PopupWindow 宽度和高度 popupWindow.setWidth(ViewGroup.LayoutParams.MATCH_PARENT); popupWindow.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT); // 设置 PopupWindow 可以获得焦点和触摸事件 popupWindow.setFocusable(true); popupWindow.setTouchable(true); popupWindow.setBackgroundDrawable(new BitmapDrawable()); // 获取省、市、县的 ListView ListView provinceList = contentView.findViewById(R.id.province_list); ListView cityList = contentView.findViewById(R.id.city_list); ListView countyList = contentView.findViewById(R.id.county_list); // 为省、市、县的 ListView 设置适配器 provinceList.setAdapter(provinceAdapter); cityList.setAdapter(cityAdapter); countyList.setAdapter(countyAdapter); // 初始化省级数据 provinceList.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // 根据点击的省份更新城市列表 cityAdapter.updateData(provinceData.get(position).getCities()); // 将县级列表数据清空 countyAdapter.clearData(); } }); // 更新县级列表数据 cityList.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // 根据点击的城市更新县级列表 countyAdapter.updateData(cityData.get(position).getCounties()); } }); // 点击县级列表中的某一项时,选定该项,并将选定的省、市、县数据返回给上层 Activity countyList.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // 获取选定的省份、城市、县级数据 String province = provinceData.get(provinceList.getSelectedItemPosition()).getName(); String city = cityData.get(cityList.getSelectedItemPosition()).getName(); String county = countyData.get(position).getName(); // 将数据返回给上层 Activity if (listener != null) { listener.onSelected(province, city, county); } // 关闭 PopupWindow popupWindow.dismiss(); } }); // 显示 PopupWindow popupWindow.showAtLocation(parentView, Gravity.BOTTOM, 0, 0); ``` 其中,provinceAdapter、cityAdapter、countyAdapter 分别为省、市、县的适配器,provinceData、cityData、countyData 分别为省、市、县的数据列表。listener 为选定省、市、县后的回调接口,用于将选定的数据返回给上层 Activity。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值