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

来源:互联网 发布:交通仿真软件功能 编辑:程序博客网 时间:2024/04/30 20:45
由于时间关系废话不多说了,直接上这次我想要实现的效果图。
这边博客的最终效果图如下所示。总共有三个下拉框,刚开始只显示出第一个下拉框出来,每选择完一个下拉框就会显示出下个下拉出来。如果将第一个下拉框设置为请选择,则第二三个下拉框边为不可见。如果同理,将第二个下拉看设置为请选择,则第三个下拉框也要设置为不可见。大概就这样。

看看项目结构,三个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)




2 0
原创粉丝点击