省市县三级联动效果

之前项目部分功能需要重构,其中就包括省市县三级联动的效果,记录下,先上图(gif看不清楚,勉强看看):

 

1、实现起来也是比较粗暴的,dialog中的listview适配省市县分别对应的Adapter,其实有点low.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:app="http://schemas.android.com/apk/res-auto"
              android:layout_width="match_parent"
              android:layout_height="300dp"
              android:background="@color/color_white"
              android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:paddingTop="8dp">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:text="所在地区"
            android:textColor="@color/color_black"
            android:textSize="14sp"/>

        <android.support.design.widget.TabLayout
            android:id="@+id/tab_bar"
            android:layout_width="match_parent"
            android:layout_height="50dip"
            android:overScrollMode="never"
            app:tabBackground="@color/color_white"
            app:tabIndicatorColor="@color/color_black"
            app:tabIndicatorHeight="2dip"
            app:tabMode="scrollable"
            app:tabPaddingStart="13dip"
            app:tabSelectedTextColor="@color/color_caselist_select"
            app:tabTextAppearance="@style/tab_text"
            app:tabTextColor="@color/color_black">
        </android.support.design.widget.TabLayout>

        <View
            style="@style/lineView"/>
        <ListView
            android:divider="@color/color_transparent"
            android:dividerHeight="0dp"
            android:scrollbars="none"
            android:layout_width="match_parent"
            android:id="@+id/lv_base"
            android:layout_height="match_parent">

        </ListView>
    </LinearLayout>


</LinearLayout>

这是dialog布局部分

2.然后是dialog中具体的代码实现部分,为方便自己看代码,差不多都写了注释:

public class AddressDialog extends Dialog implements TabLayout.OnTabSelectedListener {

    private final Context mcontext;
    @Bind(R.id.tab_bar)
    TabLayout mTabBar;
    @Bind(R.id.lv_base)
    ListView  mLvBase;
    private ArrayList<AddressProvinceBean> provinceList     = new ArrayList<>();            //省份集合
    private ArrayList<AddressCityBean>     citysList        = new ArrayList<>();            //市区集合
    private ArrayList<AddressDistrictBean> districtList     = new ArrayList<>();            //县区集合
    private ArrayList<String>              nameList         = new ArrayList<>();                         //展示的省市区名称
    private int                            provincePosition = -1;               //省份选中的位置
    private int                            cityPosition     = -1;               //市区选中的位置
    private int                            districtPosition = -1;               //县区选中的位置
    private String                    provinceName;                                        //选中的省份名称
    private String                    cityName;                                        //选中的市区名称
    private String                    districtName;                                    //选中的县区名称
    private AddressProvinceAdapter    mProvinceAdapter;                                //省级adapter
    private AddressCityAdapter        mCityAdapter;                                    //市级adapter
    private AddressDistrictAdapter    mDistrictAdapter;                                //县级adapter
    private OnAddressSelectedListener onAddressSelectedListener;                    //定义的监听,将选中的省市县等数据传给业务层


    public AddressDialog(Context context) {
        super(context, R.style.dialog_adddata_style);
        this.mcontext = context;
    }


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.dialog_address);
        ButterKnife.bind(this);
        setCanceledOnTouchOutside(true);
        init();
    }

    private void init() {
        Window window = getWindow();
        WindowManager.LayoutParams lp = window.getAttributes();
        lp.width = WindowManager.LayoutParams.MATCH_PARENT;
        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
        window.setGravity(Gravity.BOTTOM);
        window.setBackgroundDrawable(new BitmapDrawable());

        //tablayout设置第一个tab
        mTabBar.addTab(mTabBar.newTab().setText("请选择"));
       mTabBar.setOnTabSelectedListener(this);

        //获取assets下的地址json数据
        String addressJson = GsonUtils.getJson(mcontext, "address.json");

        //获取到所有的省市区的数据
        AddressCountryBean addressCountryBean = GsonUtils.getModel(addressJson, AddressCountryBean.class);
        provinceList.addAll(addressCountryBean.getProvinces());


        //新建省级adapter
        mProvinceAdapter = new AddressProvinceAdapter(mcontext, provinceList);
        mLvBase.setAdapter(mProvinceAdapter);
        //新建市级adpater
        mCityAdapter = new AddressCityAdapter(mcontext, citysList);
        //新建县级adapter
        mDistrictAdapter = new AddressDistrictAdapter(mcontext, districtList);

        //省级adapter回调,拿到选中的省的名称
        mProvinceAdapter.setOnAddressSelectedListener(new AddressProvinceAdapter.OnAddressSelectedListener() {
            @Override
            public void getAddressSelected(String name, int position) {
                provinceName = name;
                //根据选择的省的来获取到市级的数据
                citysList.clear();
                citysList.addAll(provinceList.get(position).getCitys());
                //将市的adapter设置给listview
                mLvBase.setAdapter(mCityAdapter);

                //这里可能有点复杂根据tab的数量来显示对应位置的tab显示的文字
                if (mTabBar.getTabCount() == 1){
                    //如果tab只有一个的,那就在给tabayout在新增一个tab
                    mTabBar.addTab(mTabBar.newTab().setText("请选择"));
                }else if (mTabBar.getTabCount() == 3){
                    //如果tab有三个的话,那就不用新增了
                    //把第三个tab给删除掉
                    mTabBar.removeTabAt(2);
                    //并且把第二个tab的文字改为请选择,表示还没有选择选择市
                    mTabBar.getTabAt(1).setText("请选择");
                }
                //手动把第二个tab选中
                mTabBar.getTabAt(1).select();
                //将选中的省的名称设置给第1个tab
                mTabBar.getTabAt(0).setText(provinceName);

            }
        });
        mCityAdapter.setOnAddressSelectedListener(new AddressCityAdapter.OnAddressSelectedListener() {
            @Override
            public void getAddressSelected(String name, int position) {
                cityName = name;
                //根据选中的市的名称获取到县的数据
                districtList.clear();
                districtList.addAll(citysList.get(position).getDistricts());
                //设置县的adapter
                mLvBase.setAdapter(mDistrictAdapter);
                if (mTabBar.getTabCount() == 2){
                    mTabBar.addTab(mTabBar.newTab().setText("请选择"));
                }
                mTabBar.getTabAt(2).select();
                mTabBar.getTabAt(1).setText(cityName);

            }
        });
        mDistrictAdapter.setOnAddressSelectedListener(new AddressDistrictAdapter.OnAddressSelectedListener() {
            @Override
            public void getAddressSelected(String name, int position) {
                districtName = name;
                mTabBar.getTabAt(2).setText(districtName);
                //最后将所选择的省市县的相关需要的数据回调给业务层
                onAddressSelectedListener.getAddressSelected(provinceName,cityName,districtName,districtList.get(position).getCode());
                dismiss();
            }
        });

    }


    @Override
    public void onTabSelected(TabLayout.Tab tab) {
        //tablayout的选中
        if (!TextUtils.isEmpty(tab.getText())) {
            //点击TAb的时候重新设置对应的adapter
            if (tab.getPosition() == 0) {
                //设置省份adapter
                mLvBase.setAdapter(mProvinceAdapter);
            } else if (tab.getPosition() == 1) {
                //设置市区adapter
                mLvBase.setAdapter(mCityAdapter);
            } else {
                //设置县区adapter
                mLvBase.setAdapter(mDistrictAdapter);
            }
        }
    }

    @Override
    public void onTabUnselected(TabLayout.Tab tab) {

    }

    @Override
    public void onTabReselected(TabLayout.Tab tab) {

    }

    public void setOnAddressSelectedListener(OnAddressSelectedListener onAddressSelectedListener) {
        this.onAddressSelectedListener = onAddressSelectedListener;
    }


    public interface OnAddressSelectedListener {
        void getAddressSelected(String provinceName, String cityName, String districtName, String code);
    }
}

 其实看注释很容易就能理解,点击不同的teb的时候就去加载对应的省市县的adapter,这里分别为省市县配了一个adapter.以及一个回调,把需要的信息回调到调用的地方

3,再贴一个省对应的adapter,为了数据好看,把省市县的json数据做了排序

public class AddressProvinceAdapter extends BaseAdapter {
    private final Context                   mcontext;
    private final List<AddressProvinceBean> mList;
    private       OnAddressSelectedListener onAddressSelectedListener;

    public AddressProvinceAdapter(Context context, List<AddressProvinceBean> list) {
        this.mcontext = context;
        this.mList = list;
        //按code排序(这个排不排序无所谓)
        getSort();
    }

    private void getSort() {
        Collections.sort(mList, new Comparator<AddressProvinceBean>(){
            /*
             * int compare(Person p1, Person p2) 返回一个基本类型的整型,
             * 返回负数表示:p1 小于p2,
             * 返回0 表示:p1和p2相等,
             * 返回正数表示:p1大于p2
             */
            public int compare(AddressProvinceBean a1, AddressProvinceBean a2) {
                //按照行政编码升序排列
                if(Integer.parseInt(a1.getCode()) > Integer.parseInt(a2.getCode())){
                    return 1;
                }
                if(Integer.parseInt(a1.getCode()) == Integer.parseInt(a2.getCode())){
                    return 0;
                }
                return -1;
            }
        });
    }

    @Override
    public int getCount() {
        return mList.size();
    }

    @Override
    public AddressProvinceBean getItem(int position) {
        return mList.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        final ViewHolder holder;
        if (convertView == null) {
            convertView = View.inflate(mcontext, R.layout.item_address, null);
            holder = new ViewHolder(convertView);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        if (!TextUtils.isEmpty(mList.get(position).getName())){
            holder.mTvAddress.setText(mList.get(position).getName());
        }
        //根据是否选中设置textview的选中状态
        if (mList.get(position).isSelect()){
            holder.mTvAddress.setSelected(true);
        }else {
            holder.mTvAddress.setSelected(false);
        }

        holder.mRlItem.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onAddressSelectedListener.getAddressSelected(mList.get(position).getName(),position);
                holder.mTvAddress.setSelected(true);
                //设置对应的实体类的Select的值,后续根据这个select的值显示是否选中
                for (int i = 0; i < mList.size(); i++) {
                    if (i == position){
                        mList.get(i).setSelect(true);
                    }else {
                        mList.get(i).setSelect(false);
                    }
                }
            }
        });
        return convertView;
    }

    static class ViewHolder {
        @Bind(R.id.tv_address)
        TextView       mTvAddress;
        @Bind(R.id.rl_item)
        RelativeLayout mRlItem;


        ViewHolder(View view) {
            ButterKnife.bind(this, view);
        }
    }

    public void setOnAddressSelectedListener(OnAddressSelectedListener onAddressSelectedListener) {
        this.onAddressSelectedListener = onAddressSelectedListener;
    }


    public interface OnAddressSelectedListener {
        void getAddressSelected(String provinceName, int position);
    }
}

 好了,结束,简单记录一下.

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值