Android城市级联下拉框(自定义Spinner)

由于时间关系废话不多说了,直接上这次我想要实现的效果图。
这边博客的最终效果图如下所示。总共有三个下拉框,刚开始只显示出第一个下拉框出来,每选择完一个下拉框就会显示出下个下拉出来。如果将第一个下拉框设置为请选择,则第二三个下拉框边为不可见。如果同理,将第二个下拉看设置为请选择,则第三个下拉框也要设置为不可见。大概就这样。

看看项目结构,三个java文件,两个布局文件。

1、创建一个Bean类DrowSpinnerBean.java,由于在下拉框列表中需要显示一张图片,和一个标题。因此这个类只需要两个字段,一个ImgId字段用来存放图片,一个title字段用来存放标题。
package sms.edward.per.myapplication;

/**
 * description:Bean类
 * <p/>
 * author:Edward
 * <p/>
 * 2015/10/11
 */
public class DrowSpinnerBean {
    private int imgId;
    private String title;

    public int getImgId() {
        return imgId;
    }

    public void setImgId(int imgId) {
        this.imgId = imgId;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }
}


2、说说自定义Spinner思路,数据源->适配器->控件(Spinner)显示。首先创建一个java文件命名为CustomSpinnerAdapter,接着需要重写BaseAdapter类(需要覆盖四个方法getCount(),getItem(),getItemId(),getView()),在里面自定义下拉框中每个Item的布局和数据绑定。
package sms.edward.per.myapplication;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.List;

/**
 * description:Spinner适配器
 * <p/>
 * author:Edward
 * <p/>
 * 2015/10/11
 */
public class CustomSpinnerAdapter extends BaseAdapter {
    private List<sms.edward.per.myapplication.DrowSpinnerModel> list;
    private int layoutId;
    private Context context;

    public CustomSpinnerAdapter(Context context, List<sms.edward.per.myapplication.DrowSpinnerModel> list, int layoutId) {
        this.context = context;
        this.layoutId = layoutId;
        this.list = list;
    }

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

    @Override
    public Object getItem(int i) {
        return list.get(i);
    }

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

    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        ViewHolder viewHolder = null;
        if (view == null) {
            viewHolder = new ViewHolder();
            //加载item布局
            view = LayoutInflater.from(context).inflate(layoutId, null);
            //获取实例化
            viewHolder.imageView = (ImageView) view.findViewById(R.id.image_view);
            viewHolder.textView = (TextView) view.findViewById(R.id.txt_view);
            //保存实例化的控件
            view.setTag(viewHolder);
        } else {
            //重新获取实例化的控件
            viewHolder = (ViewHolder) view.getTag();
        }

        //绑定数据
        viewHolder.imageView.setBackgroundResource(list.get(i).getImgId());
        viewHolder.textView.setText(list.get(i).getTitle());
        
        return view;
    }

    public class ViewHolder {
        ImageView imageView;
        TextView textView;
    }
}

在屏幕滑动的过程中,最顶部或最底部的Item由可见状态转变为不可见状态的时候都会回调getView方法。获取原来的Item里面的控件将其重新绑上数据。具体绘制原理请各位搜索一下吧。

3、设置好适配器之后,我们需要再写一个适配器的布局文件,将这个文件命名为activity_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:background="#ffffff"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/image_view"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_centerVertical="true"
        android:background="@mipmap/ic_launcher" />

    <TextView
        android:id="@+id/txt_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_toRightOf="@+id/image_view"
        android:text="测试" />
</RelativeLayout>
很简单的一个布局,效果如图所示。



4、做好适配器的工作之后,就开始设置主页面的布局,创建一个布局文件,文件名为activity_main.xml,在一个线性布局中放三个Spinner
<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:background="#ffffff"
    android:layout_height="match_parent"
    android:orientation="horizontal">


    <Spinner
        android:id="@+id/spinner1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:spinnerMode="dropdown" />

    <Spinner
        android:id="@+id/spinner2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:spinnerMode="dropdown"
        android:visibility="invisible" />

    <Spinner
        android:id="@+id/spinner3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:spinnerMode="dropdown"
        android:visibility="invisible" />


</LinearLayout>
这里需要特别说明的是visibility属性的三个参数:VISIBLE(可见),INVISIBLE(不可见,但会占据位置),GONE(不可见,不会占据位置)

5、设置主布局的代码,创建一个MainActivity.java文件。在这个文件之中创建了三个List<DrowSpinnerBean>用来存放数据。将主要的逻辑操作都放在Spinner的监听器事件里面。具体请看代码注释。
package sms.edward.per.myapplication;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Spinner;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

/**
 * 此Demo博客地址:http://blog.csdn.net/u012814441/article/details/49073457
 * <p/>
 * author:Edward
 */
public class MainActivity extends Activity {
    private List<DrowSpinnerBean> list1;
    private List<DrowSpinnerBean> list2;
    private List<DrowSpinnerBean> list3;
    private Spinner spinner1, spinner2, spinner3;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        spinner1 = (Spinner) findViewById(R.id.spinner1);
        spinner2 = (Spinner) findViewById(R.id.spinner2);
        spinner3 = (Spinner) findViewById(R.id.spinner3);

        //加载省份列表
        loadProvince();
        //设置点击事件
        spinner1.setOnItemSelectedListener(new Spinner1ClickListener());
        //加载城市列表
        loadCity();
        //设置点击事件
        spinner2.setOnItemSelectedListener(new Spinner2ClickListener());
        //加载区域列表
        loadGZArea();
        //设置点击事件
        spinner3.setOnItemSelectedListener(new Spinner3ClickListener());

    }

    /**
     * 加载省份
     */
    public void loadProvince() {
        list1 = new ArrayList<>();
        DrowSpinnerBean modelOne;
        modelOne = new DrowSpinnerBean();
        modelOne.setImgId(R.mipmap.edward1);
        modelOne.setTitle("请选择");
        list1.add(modelOne);

        modelOne = new DrowSpinnerBean();
        modelOne.setImgId(R.mipmap.edward15);
        modelOne.setTitle("广东省");
        list1.add(modelOne);

        CustomSpinnerAdapter adapterOne = new CustomSpinnerAdapter(this, list1, R.layout.activity_item);
        spinner1.setAdapter(adapterOne);
    }

    /**
     * 加载城市列表
     */
    public void loadCity() {
        list2 = new ArrayList<>();
        DrowSpinnerBean modelTwo;
        modelTwo = new DrowSpinnerBean();
        modelTwo.setImgId(R.mipmap.edward1);
        modelTwo.setTitle("请选择");
        list2.add(modelTwo);

        modelTwo = new DrowSpinnerBean();
        modelTwo.setImgId(R.mipmap.edward15);
        modelTwo.setTitle("广州市");
        list2.add(modelTwo);

        modelTwo = new DrowSpinnerBean();
        modelTwo.setImgId(R.mipmap.edward15);
        modelTwo.setTitle("深圳市");
        list2.add(modelTwo);

        CustomSpinnerAdapter adapterTwo = new CustomSpinnerAdapter(this, list2, R.layout.activity_item);
        spinner2.setAdapter(adapterTwo);
    }

    /**
     * 加载广州区域列表
     */
    public void loadGZArea() {
        list3 = new ArrayList<>();
        DrowSpinnerBean modelThree;
        modelThree = new DrowSpinnerBean();
        modelThree.setImgId(R.mipmap.edward1);
        modelThree.setTitle("请选择");
        list3.add(modelThree);

        modelThree = new DrowSpinnerBean();
        modelThree.setImgId(R.mipmap.edward15);
        modelThree.setTitle("天河区");
        list3.add(modelThree);

        modelThree = new DrowSpinnerBean();
        modelThree.setImgId(R.mipmap.edward15);
        modelThree.setTitle("越秀区");
        list3.add(modelThree);

        CustomSpinnerAdapter adapterThree = new CustomSpinnerAdapter(this, list3, R.layout.activity_item);
        spinner3.setAdapter(adapterThree);
    }

    /**
     * 加载深圳区域列表
     */
    public void loadSZArea() {
        list3 = new ArrayList<>();

        DrowSpinnerBean modelThree = null;
        modelThree = new DrowSpinnerBean();
        modelThree.setImgId(R.mipmap.edward15);
        modelThree.setTitle("请选择");
        list3.add(modelThree);

        modelThree = new DrowSpinnerBean();
        modelThree.setImgId(R.mipmap.edward15);
        modelThree.setTitle("龙岗区");
        list3.add(modelThree);

        modelThree = new DrowSpinnerBean();
        modelThree.setImgId(R.mipmap.edward15);
        modelThree.setTitle("南山区");
        list3.add(modelThree);

        CustomSpinnerAdapter adapterThree = new CustomSpinnerAdapter(MainActivity.this, list3, R.layout.activity_item);
        spinner3.setAdapter(adapterThree);
    }

    /**
     * Spinner1点击事件
     */
    public class Spinner1ClickListener implements AdapterView.OnItemSelectedListener {

        @Override
        public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
            DrowSpinnerBean model = (DrowSpinnerBean) adapterView.getItemAtPosition(i);
            //判断是否选择城市,如果没有选择那么就隐藏Spinner2,Spinner3两个下拉框,否则显示Spinner2下拉框,继续隐藏Spinner3
            if (model.getTitle().equals("请选择")) {
                spinner2.setVisibility(View.INVISIBLE);
                spinner3.setVisibility(View.INVISIBLE);
            } else {
                spinner2.setVisibility(View.VISIBLE);

                //将第二个下拉框的选项重新设置为选中“请选择”这个选项。
                spinner2.setSelection(0);
            }

            Toast.makeText(getApplicationContext(), model.getTitle(), Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onNothingSelected(AdapterView<?> adapterView) {

        }
    }

    /**
     * Spinner2点击事件
     */
    public class Spinner2ClickListener implements AdapterView.OnItemSelectedListener {

        @Override
        public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
            DrowSpinnerBean model = (DrowSpinnerBean) adapterView.getItemAtPosition(i);
            if (model.getTitle().equals("请选择")) {
                spinner3.setVisibility(View.INVISIBLE);
            } else {
                //显示第三个Spinner3
                spinner3.setVisibility(View.VISIBLE);

                if (model.getTitle().equals("深圳市")) {
                    //重新加载深圳区域列表
                    loadSZArea();
                } else if (model.getTitle().equals("广州市")) {
                    //重新加载广州区域列表
                    loadGZArea();
                }
            }
            Toast.makeText(getApplicationContext(), model.getTitle(), Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onNothingSelected(AdapterView<?> adapterView) {

        }
    }

    /**
     * Spinner3点击事件
     */
    public class Spinner3ClickListener implements AdapterView.OnItemSelectedListener {

        @Override
        public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
            DrowSpinnerBean model = (DrowSpinnerBean) adapterView.getItemAtPosition(i);
            Toast.makeText(getApplicationContext(), model.getTitle(), Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onNothingSelected(AdapterView<?> adapterView) {

        }
    }

}


最终的效果图跟开头的git动画一样。

完整代码请戳这里
Android城市级联下拉框(自定义Spinner)




评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值