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

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

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

1、创建一个Bean类DrowSpinnerBean.java,由于在下拉框列表中需要显示一张图片,和一个标题。因此这个类只需要两个字段,一个ImgId字段用来存放图片,一个title字段用来存放标题。
[java] view plain copy
print?
  1. package sms.edward.per.myapplication;  
  2.   
  3. /** 
  4.  * description:Bean类 
  5.  * <p/> 
  6.  * author:Edward 
  7.  * <p/> 
  8.  * 2015/10/11 
  9.  */  
  10. public class DrowSpinnerBean {  
  11.     private int imgId;  
  12.     private String title;  
  13.   
  14.     public int getImgId() {  
  15.         return imgId;  
  16.     }  
  17.   
  18.     public void setImgId(int imgId) {  
  19.         this.imgId = imgId;  
  20.     }  
  21.   
  22.     public String getTitle() {  
  23.         return title;  
  24.     }  
  25.   
  26.     public void setTitle(String title) {  
  27.         this.title = title;  
  28.     }  
  29. }  

2、说说自定义Spinner思路,数据源->适配器->控件(Spinner)显示。首先创建一个java文件命名为CustomSpinnerAdapter,接着需要重写BaseAdapter类(需要覆盖四个方法getCount(),getItem(),getItemId(),getView()),在里面自定义下拉框中每个Item的布局和数据绑定。
[java] view plain copy
print?
  1. package sms.edward.per.myapplication;  
  2.   
  3. import android.content.Context;  
  4. import android.view.LayoutInflater;  
  5. import android.view.View;  
  6. import android.view.ViewGroup;  
  7. import android.widget.BaseAdapter;  
  8. import android.widget.ImageView;  
  9. import android.widget.TextView;  
  10.   
  11. import java.util.List;  
  12.   
  13. /** 
  14.  * description:Spinner适配器 
  15.  * <p/> 
  16.  * author:Edward 
  17.  * <p/> 
  18.  * 2015/10/11 
  19.  */  
  20. public class CustomSpinnerAdapter extends BaseAdapter {  
  21.     private List<sms.edward.per.myapplication.DrowSpinnerModel> list;  
  22.     private int layoutId;  
  23.     private Context context;  
  24.   
  25.     public CustomSpinnerAdapter(Context context, List<sms.edward.per.myapplication.DrowSpinnerModel> list, int layoutId) {  
  26.         this.context = context;  
  27.         this.layoutId = layoutId;  
  28.         this.list = list;  
  29.     }  
  30.   
  31.     @Override  
  32.     public int getCount() {  
  33.         return list.size();  
  34.     }  
  35.   
  36.     @Override  
  37.     public Object getItem(int i) {  
  38.         return list.get(i);  
  39.     }  
  40.   
  41.     @Override  
  42.     public long getItemId(int i) {  
  43.         return i;  
  44.     }  
  45.   
  46.     @Override  
  47.     public View getView(int i, View view, ViewGroup viewGroup) {  
  48.         ViewHolder viewHolder = null;  
  49.         if (view == null) {  
  50.             viewHolder = new ViewHolder();  
  51.             //加载item布局  
  52.             view = LayoutInflater.from(context).inflate(layoutId, null);  
  53.             //获取实例化  
  54.             viewHolder.imageView = (ImageView) view.findViewById(R.id.image_view);  
  55.             viewHolder.textView = (TextView) view.findViewById(R.id.txt_view);  
  56.             //保存实例化的控件  
  57.             view.setTag(viewHolder);  
  58.         } else {  
  59.             //重新获取实例化的控件  
  60.             viewHolder = (ViewHolder) view.getTag();  
  61.         }  
  62.   
  63.         //绑定数据  
  64.         viewHolder.imageView.setBackgroundResource(list.get(i).getImgId());  
  65.         viewHolder.textView.setText(list.get(i).getTitle());  
  66.           
  67.         return view;  
  68.     }  
  69.   
  70.     public class ViewHolder {  
  71.         ImageView imageView;  
  72.         TextView textView;  
  73.     }  
  74. }  
在屏幕滑动的过程中,最顶部或最底部的Item由可见状态转变为不可见状态的时候都会回调getView方法。获取原来的Item里面的控件将其重新绑上数据。具体绘制原理请各位搜索一下吧。

3、设置好适配器之后,我们需要再写一个适配器的布局文件,将这个文件命名为activity_item.xml
[java] view plain copy
print?
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     xmlns:tools="http://schemas.android.com/tools"  
  4.     android:layout_width="match_parent"  
  5.     android:background="#ffffff"  
  6.     android:layout_height="match_parent">  
  7.   
  8.     <ImageView  
  9.         android:id="@+id/image_view"  
  10.         android:layout_width="50dp"  
  11.         android:layout_height="50dp"  
  12.         android:layout_centerVertical="true"  
  13.         android:background="@mipmap/ic_launcher" />  
  14.   
  15.     <TextView  
  16.         android:id="@+id/txt_view"  
  17.         android:layout_width="wrap_content"  
  18.         android:layout_height="wrap_content"  
  19.         android:layout_centerVertical="true"  
  20.         android:layout_toRightOf="@+id/image_view"  
  21.         android:text="测试" />  
  22. </RelativeLayout>  
很简单的一个布局,效果如图所示。



4、做好适配器的工作之后,就开始设置主页面的布局,创建一个布局文件,文件名为activity_main.xml,在一个线性布局中放三个Spinner
[java] view plain copy
print?
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     xmlns:app="http://schemas.android.com/apk/res-auto"  
  4.     xmlns:tools="http://schemas.android.com/tools"  
  5.     android:layout_width="match_parent"  
  6.     android:background="#ffffff"  
  7.     android:layout_height="match_parent"  
  8.     android:orientation="horizontal">  
  9.   
  10.   
  11.     <Spinner  
  12.         android:id="@+id/spinner1"  
  13.         android:layout_width="match_parent"  
  14.         android:layout_height="wrap_content"  
  15.         android:layout_weight="1"  
  16.         android:spinnerMode="dropdown" />  
  17.   
  18.     <Spinner  
  19.         android:id="@+id/spinner2"  
  20.         android:layout_width="match_parent"  
  21.         android:layout_height="wrap_content"  
  22.         android:layout_weight="1"  
  23.         android:spinnerMode="dropdown"  
  24.         android:visibility="invisible" />  
  25.   
  26.     <Spinner  
  27.         android:id="@+id/spinner3"  
  28.         android:layout_width="match_parent"  
  29.         android:layout_height="wrap_content"  
  30.         android:layout_weight="1"  
  31.         android:spinnerMode="dropdown"  
  32.         android:visibility="invisible" />  
  33.   
  34.   
  35. </LinearLayout>  
这里需要特别说明的是visibility属性的三个参数:VISIBLE(可见),INVISIBLE(不可见,但会占据位置),GONE(不可见,不会占据位置)

5、设置主布局的代码,创建一个MainActivity.java文件。在这个文件之中创建了三个List<DrowSpinnerBean>用来存放数据。将主要的逻辑操作都放在Spinner的监听器事件里面。具体请看代码注释。
[java] view plain copy
print?
  1. package sms.edward.per.myapplication;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.view.View;  
  6. import android.widget.AdapterView;  
  7. import android.widget.Spinner;  
  8. import android.widget.Toast;  
  9.   
  10. import java.util.ArrayList;  
  11. import java.util.List;  
  12.   
  13. /** 
  14.  * 此Demo博客地址:http://blog.csdn.net/u012814441/article/details/49073457 
  15.  * <p/> 
  16.  * author:Edward 
  17.  */  
  18. public class MainActivity extends Activity {  
  19.     private List<DrowSpinnerBean> list1;  
  20.     private List<DrowSpinnerBean> list2;  
  21.     private List<DrowSpinnerBean> list3;  
  22.     private Spinner spinner1, spinner2, spinner3;  
  23.   
  24.     @Override  
  25.     protected void onCreate(Bundle savedInstanceState) {  
  26.         super.onCreate(savedInstanceState);  
  27.         setContentView(R.layout.activity_main);  
  28.   
  29.         spinner1 = (Spinner) findViewById(R.id.spinner1);  
  30.         spinner2 = (Spinner) findViewById(R.id.spinner2);  
  31.         spinner3 = (Spinner) findViewById(R.id.spinner3);  
  32.   
  33.         //加载省份列表  
  34.         loadProvince();  
  35.         //设置点击事件  
  36.         spinner1.setOnItemSelectedListener(new Spinner1ClickListener());  
  37.         //加载城市列表  
  38.         loadCity();  
  39.         //设置点击事件  
  40.         spinner2.setOnItemSelectedListener(new Spinner2ClickListener());  
  41.         //加载区域列表  
  42.         loadGZArea();  
  43.         //设置点击事件  
  44.         spinner3.setOnItemSelectedListener(new Spinner3ClickListener());  
  45.   
  46.     }  
  47.   
  48.     /** 
  49.      * 加载省份 
  50.      */  
  51.     public void loadProvince() {  
  52.         list1 = new ArrayList<>();  
  53.         DrowSpinnerBean modelOne;  
  54.         modelOne = new DrowSpinnerBean();  
  55.         modelOne.setImgId(R.mipmap.edward1);  
  56.         modelOne.setTitle("请选择");  
  57.         list1.add(modelOne);  
  58.   
  59.         modelOne = new DrowSpinnerBean();  
  60.         modelOne.setImgId(R.mipmap.edward15);  
  61.         modelOne.setTitle("广东省");  
  62.         list1.add(modelOne);  
  63.   
  64.         CustomSpinnerAdapter adapterOne = new CustomSpinnerAdapter(this, list1, R.layout.activity_item);  
  65.         spinner1.setAdapter(adapterOne);  
  66.     }  
  67.   
  68.     /** 
  69.      * 加载城市列表 
  70.      */  
  71.     public void loadCity() {  
  72.         list2 = new ArrayList<>();  
  73.         DrowSpinnerBean modelTwo;  
  74.         modelTwo = new DrowSpinnerBean();  
  75.         modelTwo.setImgId(R.mipmap.edward1);  
  76.         modelTwo.setTitle("请选择");  
  77.         list2.add(modelTwo);  
  78.   
  79.         modelTwo = new DrowSpinnerBean();  
  80.         modelTwo.setImgId(R.mipmap.edward15);  
  81.         modelTwo.setTitle("广州市");  
  82.         list2.add(modelTwo);  
  83.   
  84.         modelTwo = new DrowSpinnerBean();  
  85.         modelTwo.setImgId(R.mipmap.edward15);  
  86.         modelTwo.setTitle("深圳市");  
  87.         list2.add(modelTwo);  
  88.   
  89.         CustomSpinnerAdapter adapterTwo = new CustomSpinnerAdapter(this, list2, R.layout.activity_item);  
  90.         spinner2.setAdapter(adapterTwo);  
  91.     }  
  92.   
  93.     /** 
  94.      * 加载广州区域列表 
  95.      */  
  96.     public void loadGZArea() {  
  97.         list3 = new ArrayList<>();  
  98.         DrowSpinnerBean modelThree;  
  99.         modelThree = new DrowSpinnerBean();  
  100.         modelThree.setImgId(R.mipmap.edward1);  
  101.         modelThree.setTitle("请选择");  
  102.         list3.add(modelThree);  
  103.   
  104.         modelThree = new DrowSpinnerBean();  
  105.         modelThree.setImgId(R.mipmap.edward15);  
  106.         modelThree.setTitle("天河区");  
  107.         list3.add(modelThree);  
  108.   
  109.         modelThree = new DrowSpinnerBean();  
  110.         modelThree.setImgId(R.mipmap.edward15);  
  111.         modelThree.setTitle("越秀区");  
  112.         list3.add(modelThree);  
  113.   
  114.         CustomSpinnerAdapter adapterThree = new CustomSpinnerAdapter(this, list3, R.layout.activity_item);  
  115.         spinner3.setAdapter(adapterThree);  
  116.     }  
  117.   
  118.     /** 
  119.      * 加载深圳区域列表 
  120.      */  
  121.     public void loadSZArea() {  
  122.         list3 = new ArrayList<>();  
  123.   
  124.         DrowSpinnerBean modelThree = null;  
  125.         modelThree = new DrowSpinnerBean();  
  126.         modelThree.setImgId(R.mipmap.edward15);  
  127.         modelThree.setTitle("请选择");  
  128.         list3.add(modelThree);  
  129.   
  130.         modelThree = new DrowSpinnerBean();  
  131.         modelThree.setImgId(R.mipmap.edward15);  
  132.         modelThree.setTitle("龙岗区");  
  133.         list3.add(modelThree);  
  134.   
  135.         modelThree = new DrowSpinnerBean();  
  136.         modelThree.setImgId(R.mipmap.edward15);  
  137.         modelThree.setTitle("南山区");  
  138.         list3.add(modelThree);  
  139.   
  140.         CustomSpinnerAdapter adapterThree = new CustomSpinnerAdapter(MainActivity.this, list3, R.layout.activity_item);  
  141.         spinner3.setAdapter(adapterThree);  
  142.     }  
  143.   
  144.     /** 
  145.      * Spinner1点击事件 
  146.      */  
  147.     public class Spinner1ClickListener implements AdapterView.OnItemSelectedListener {  
  148.   
  149.         @Override  
  150.         public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {  
  151.             DrowSpinnerBean model = (DrowSpinnerBean) adapterView.getItemAtPosition(i);  
  152.             //判断是否选择城市,如果没有选择那么就隐藏Spinner2,Spinner3两个下拉框,否则显示Spinner2下拉框,继续隐藏Spinner3  
  153.             if (model.getTitle().equals("请选择")) {  
  154.                 spinner2.setVisibility(View.INVISIBLE);  
  155.                 spinner3.setVisibility(View.INVISIBLE);  
  156.             } else {  
  157.                 spinner2.setVisibility(View.VISIBLE);  
  158.   
  159.                 //将第二个下拉框的选项重新设置为选中“请选择”这个选项。  
  160.                 spinner2.setSelection(0);  
  161.             }  
  162.   
  163.             Toast.makeText(getApplicationContext(), model.getTitle(), Toast.LENGTH_SHORT).show();  
  164.         }  
  165.   
  166.         @Override  
  167.         public void onNothingSelected(AdapterView<?> adapterView) {  
  168.   
  169.         }  
  170.     }  
  171.   
  172.     /** 
  173.      * Spinner2点击事件 
  174.      */  
  175.     public class Spinner2ClickListener implements AdapterView.OnItemSelectedListener {  
  176.   
  177.         @Override  
  178.         public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {  
  179.             DrowSpinnerBean model = (DrowSpinnerBean) adapterView.getItemAtPosition(i);  
  180.             if (model.getTitle().equals("请选择")) {  
  181.                 spinner3.setVisibility(View.INVISIBLE);  
  182.             } else {  
  183.                 //显示第三个Spinner3  
  184.                 spinner3.setVisibility(View.VISIBLE);  
  185.   
  186.                 if (model.getTitle().equals("深圳市")) {  
  187.                     //重新加载深圳区域列表  
  188.                     loadSZArea();  
  189.                 } else if (model.getTitle().equals("广州市")) {  
  190.                     //重新加载广州区域列表  
  191.                     loadGZArea();  
  192.                 }  
  193.             }  
  194.             Toast.makeText(getApplicationContext(), model.getTitle(), Toast.LENGTH_SHORT).show();  
  195.         }  
  196.   
  197.         @Override  
  198.         public void onNothingSelected(AdapterView<?> adapterView) {  
  199.   
  200.         }  
  201.     }  
  202.   
  203.     /** 
  204.      * Spinner3点击事件 
  205.      */  
  206.     public class Spinner3ClickListener implements AdapterView.OnItemSelectedListener {  
  207.   
  208.         @Override  
  209.         public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {  
  210.             DrowSpinnerBean model = (DrowSpinnerBean) adapterView.getItemAtPosition(i);  
  211.             Toast.makeText(getApplicationContext(), model.getTitle(), Toast.LENGTH_SHORT).show();  
  212.         }  
  213.   
  214.         @Override  
  215.         public void onNothingSelected(AdapterView<?> adapterView) {  
  216.   
  217.         }  
  218.     }  
  219.   
  220. }  


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

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



0 0
原创粉丝点击