【详细】Spinner实现三级联动功能

29 篇文章 0 订阅
19 篇文章 1 订阅

1. 需求分析

       在实际开发中,我们经常遇到要求省市县三级联动的下拉框需求,如下图,针对这类需求,我们常用Spinner控件去实现。当用户选择Spinner控件的时候,可以提供一个下拉列表将所有可选的项列出来。供用户选择。

      今天,我就研究一下怎么实现三级联动的需求。

2. 实现流程

  • 在布局文件中添加Spinner控件
  • 在Acitvity中获取控件
  • 给Spinner绑定一个适配器
  • 编辑Spinner中单个item布局(本文采用testview)
  • 绑定点击事件的监听

2.1 布局文件中添加Spinner控件

           在布局中,将三个Spinner的layout_weight = "1",可以实现三等分的效果。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff"
    android:orientation="horizontal"
    tools:context=".MainActivity">

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

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

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

</LinearLayout>

2.2 在Acitvity中获取控件

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.spanner_layout);
    // 获取控件
    spinner1 = (Spinner) findViewById(R.id.spinner1);
    spinner2 = (Spinner) findViewById(R.id.spinner2);
    spinner3 = (Spinner) findViewById(R.id.spinner3);
   }

2.3 Spinner绑定适配器

/**
 * Created by hangli on 2018/11/9.
 * @description: Spinner适配器
 */

public class SpinnerAdapter extends BaseAdapter {
    private Context context;
    private String[] array;
    private int layoutId;

    /**
     * 构造方法
     * @param context 上下文对象
     * @param array  数组
     * @param layoutId 布局Id
     */
    public SpinnerAdapter(Context context, String[] array, int layoutId) {
        this.context = context;
        this.array = array;
        this.layoutId = layoutId;
    }

    /**
     * 获取Item总数
     * @return
     */
    @Override
    public int getCount() {
        return array.length;
    }

    /**
     * 获取一个Item对象
     * @param position
     * @return
     */
    @Override
    public Object getItem(int position) {
        return array[position];
    }

    /**
     * 获取指定item的ID
     * @param position
     * @return
     */
    @Override
    public long getItemId(int position) {
        return position;
    }

    /**
     * 绘制的内容均在此实现
     * @param position position就是位置从0开始
     * @param convertView convertView是Spinner中每一项要显示的view
     * @param parent parent就是父窗体了,也就是Spinner
     * @return
     */
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View item = convertView != null ? convertView : View.inflate(context, layoutId, null);
        TextView txt_name = (TextView) item.findViewById(R.id.txt_name);
        txt_name.setText(array[position]);
        return item;
    }
}

2.4 编辑item布局

       适配器是展示数据的载体,对于一个适配器,我们往往需要一个独立item布局,spanner控件也不例外。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#fff"
    android:gravity="center"
    android:orientation="horizontal"
    android:padding="5dp">

    <TextView
        android:id="@+id/txt_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="名称"
        android:textSize="16dp" />
</LinearLayout>

2.5 绑定点击事件的监听

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

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

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

PS 对于选中不同地区,后续区域更改,我们可以分别在控制Spanner2,Spanner3的显示隐藏,同时在加载adapter的时候,选中对应地区的数据。实现不了的小伙伴,请参考我的完整代码~

3. 完整Activity代码

/**
 * Created by hangli on 2018/11/9.
 */
public class AndroidTestActivity extends Activity {
    private Spinner spinner1, spinner2, spinner3;

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

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

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

    /**
     * 加载省份列表
     */
    public void loadProvince() {
        String[] array1 = new String[]{"请选择", "宁夏回族自治区","北京市","广东省"};
        SpinnerAdapter adapterOne = new SpinnerAdapter(this, array1, R.layout.spanner_item);
        spinner1.setAdapter(adapterOne);
    }



    /**
     * 加载城市列表
     */
    public void loadCity() {
        String[] array2 = new String[]{"请选择", "广州市", "深圳市"};
        SpinnerAdapter modelTwo = new SpinnerAdapter(this, array2, R.layout.spanner_item);
        spinner2.setAdapter(modelTwo);
    }

    /**
     * 加载广州区域列表
     */
    public void loadGZArea() {
        String[] array3 = new String[]{"请选择", "天河区", "越秀区", "荔湾区", "海珠区", "萝岗区", "白云区", "黄埔区", "花都区"};
        SpinnerAdapter modelThree = new SpinnerAdapter(this, array3, R.layout.spanner_item);
        spinner3.setAdapter(modelThree);
    }

    /**
     * 加载深圳区域列表
     */
    public void loadSZArea() {
        String[] array3 = new String[]{"请选择", "龙岗区", "南山区", "福田区", "罗湖区", "盐田区", "宝安区"};
        SpinnerAdapter modelThree = new SpinnerAdapter(this, array3, R.layout.spanner_item);
        spinner3.setAdapter(modelThree);
    }

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

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

                //将第二个下拉框的选项重新设置为选中“请选择”这个选项。
                spinner2.setSelection(0);
                if (str.equals("北京市")){
                    loadBJArea();
                }else if (str.equals("宁夏回族自治区")){
                    loadNXArea();
                }
            }

            Toast.makeText(getApplicationContext(), str, Toast.LENGTH_SHORT).show();
        }

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

        }
    }

    /**
     * 加载宁夏区域列表
     */
    private void loadNXArea() {
        String[] array2 = new String[]{"请选择", "银川市", "吴忠市", "石嘴山市", "固原市","中卫市区"};
        SpinnerAdapter modelTwo = new SpinnerAdapter(this, array2, R.layout.spanner_item);
        spinner2.setAdapter(modelTwo);
    }

    /**
     * 加载北京区域列表
     */
    private void loadBJArea() {
        String[] array2 = new String[]{"请选择", "海淀区", "朝阳区", "东城区", "西城区","丰台区","石景山区"};
        SpinnerAdapter modelTwo = new SpinnerAdapter(this, array2, R.layout.spanner_item);
        spinner2.setAdapter(modelTwo);
    }

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

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

                if (str.equals("深圳市")) {
                    //重新加载深圳区域列表
                    loadSZArea();
                } else if (str.equals("广州市")) {
                    //重新加载广州区域列表
                    loadGZArea();
                }
            }
            Toast.makeText(getApplicationContext(), str, 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) {
            String str = (String) adapterView.getItemAtPosition(i);
            Toast.makeText(getApplicationContext(), str, Toast.LENGTH_SHORT).show();
        }

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

        }
    }
}

 

 

  • 6
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spinner 的二级联动可以通过以下步骤实现: 1. 在 layout 文件中添加两个 Spinner 控件,一个用于选择一级选项,另一个用于选择二级选项。 2. 在 Java 代码中为第一个 Spinner 设置适配器,适配器中包含一级选项的数据源。 3. 在第一个 Spinner 的选择事件中获取当前选择的一级选项,并根据该选项获取对应的二级选项数据源。 4. 为第二个 Spinner 设置适配器,适配器中包含二级选项的数据源。 5. 在第二个 Spinner 的选择事件中获取当前选择的二级选项。 下面是一个简单的示例代码,演示如何实现 Spinner 的二级联动: ```java // 获取 layout 文件中的 Spinner 控件 Spinner spinner1 = findViewById(R.id.spinner1); Spinner spinner2 = findViewById(R.id.spinner2); // 定义一级选项和二级选项的数据源 String[] items1 = {"选项1", "选项2", "选项3"}; String[][] items2 = { {"选项1-1", "选项1-2", "选项1-3"}, {"选项2-1", "选项2-2", "选项2-3"}, {"选项3-1", "选项3-2", "选项3-3"} }; // 为第一个 Spinner 设置适配器 ArrayAdapter<String> adapter1 = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, items1); adapter1.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinner1.setAdapter(adapter1); // 第一个 Spinner 的选择事件 spinner1.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { // 获取当前选择的一级选项 String item1 = items1[position]; // 根据一级选项获取对应的二级选项数据源 String[] item2 = items2[position]; // 为第二个 Spinner 设置适配器 ArrayAdapter<String> adapter2 = new ArrayAdapter<>(MainActivity.this, android.R.layout.simple_spinner_item, item2); adapter2.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinner2.setAdapter(adapter2); } @Override public void onNothingSelected(AdapterView<?> parent) { // do nothing } }); // 第二个 Spinner 的选择事件 spinner2.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { // 获取当前选择的二级选项 String item2 = (String) parent.getItemAtPosition(position); // do something with item2 } @Override public void onNothingSelected(AdapterView<?> parent) { // do nothing } }); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值