前言

最近一直在讲AndroidUI的开发,今天讲一下Spinner控件,这是一个列表选择框,可以弹出一个列表供用户选择。在本片博客中,会讲解Spinner的基本属性以及设置之后的效果,以及使用SimpleAdapter绑定自定义格式的数据到Spinner中。

Spinner

Spinner 是一个列表选择框,会在用户选择后,展示一个列表供用户进行选择。Spinner是ViewGroup的间接子类,它和其他的Android控件一样,数据需要使用Adapter进行封装。

下面介绍一下Spinner的常用XML属性,Android也为其属性提供了相应的getter、setter方法:

  • android:spinnerMode:列表显示的模式,有两个选择,为弹出列表(dialog)以及下拉列表(dropdown),如果不特别设置,为下拉列表。。
  • android:entries:使用<string-array.../>资源配置数据源。
  • android:prompt:对当前下拉列表设置标题,仅在dialog模式下有效。传递一个“@string/name”资源,需要在需要在资源文件中定义<string.../>。

作为一个列表选择控件,Spinner具有一些选中选项可以触发的事件,但它本身没有定义这些事件,均继承自间接父类 AdapterView 。Spinner支持的几个常用事件有以下几个:

  • AdapterView.OnItemCLickListener:列表项被点击时触发。
  • AdapterView.OnItemLongClickListener:列表项被长按时触发。
  • AdapterView.OnItemSelectedListener:列表项被选择时触发。

PS:因为适配器可以设置各种不同的样式,有选择、单选、多选,所以OnItemCLickListener和OnItemSelectedListener是适用于不同场景的。

Spinner的数据绑定

对于Spinner展示的数据源,一般使用两种方式设定数据:

  • 通过XML资源文件设置,这种方式比较死板,但是如果仅仅需要展示固定的、简单的数据,这种方式还是可以考虑的,比较直观。
  • 使用Adapter接口设置,这是最常见的方式,动态、灵活,可以设定各种样式以及数据来源。

先来讲讲通过XML资源文件设置Spinner数据的方式,首先需要在/res/values目录下新建XML格式的资源文件,名字不重要,但是一般会使用strings.xml。在其中的<resourse.../>标签下,定义<string-array.../>标签,通过它中的<item.../>标签来设置选择数据。

XML文件结构:

<resource>

<string-array name="arrayname">

<item>item1</item>

<item>item2</item>

<item>item3</item>

</string-array>

<resource>

通过适配器Adapter可以设定比较复杂的展示效果,一般项目中比较常用的也是这种方式。但是如果对于动态的、简单的数据,可以使用ArrayAdapter对象来设置适配器,关于ArrayAdapter类的介绍,在我的另外一篇博客中有介绍,不了解的朋友可以先看看: Android--UI之AutoCompleteTextView 。

下面通过一个示例,讲解一下上面说的属性、事件,以及使用ArrayAdapter和XML资源文件设定简单数据,代码中注释已经说的很清楚了,这里就不再累述了。

布局代码:

  1. 1 <?xml version="1.0" encoding="utf-8"?>
  2. 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. 3 android:layout_width="match_parent"
  4. 4 android:layout_height="match_parent"
  5. 5 android:orientation="vertical" >
  6. 6
  7. 7 <TextView
  8. 8 android:layout_width="wrap_content"
  9. 9 android:layout_height="wrap_content"
  10. 10 android:text="弹出的Spinner" />
  11. 11
  12. 12 <Spinner
  13. 13 android:id="@+id/spinnerBase"
  14. 14 android:layout_width="match_parent"
  15. 15 android:layout_height="wrap_content"
  16. 16 android:spinnerMode="dialog" />
  17. 17
  18. 18 <TextView
  19. 19 android:layout_width="wrap_content"
  20. 20 android:layout_height="wrap_content"
  21. 21 android:text="下拉的Spinner(默认)" />
  22. 22
  23. 23 <Spinner
  24. 24 android:id="@+id/spinnerBase1"
  25. 25 android:layout_width="match_parent"
  26. 26 android:layout_height="wrap_content"
  27. 27 android:spinnerMode="dropdown" />
  28. 28
  29. 29 <TextView
  30. 30 android:layout_width="wrap_content"
  31. 31 android:layout_height="wrap_content"
  32. 32 android:text="entries绑定数据源" />
  33. 33
  34. 34 <Spinner
  35. 35 android:id="@+id/spinnerBase2"
  36. 36 android:layout_width="match_parent"
  37. 37 android:layout_height="wrap_content"
  38. 38 android:entries="@array/beijing" />
  39. 39
  40. 40 <TextView
  41. 41 android:layout_width="wrap_content"
  42. 42 android:layout_height="wrap_content"
  43. 43 android:text="弹出带标题的Dialog,并且使用entries绑定数据源" />
  44. 44
  45. 45 <Spinner
  46. 46 android:id="@+id/spinnerBase3"
  47. 47 android:layout_width="match_parent"
  48. 48 android:layout_height="wrap_content"
  49. 49 android:entries="@array/beijing"
  50. 50 android:prompt="@string/beij_prompt"
  51. 51 android:spinnerMode="dialog" />
  52. 52
  53. 53 </LinearLayout>

实现代码:

  1. 1 package com.bgxt.datatimepickerdemo;
  2. 2
  3. 3 import java.util.ArrayList;
  4. 4 import java.util.List;
  5. 5
  6. 6 import android.app.Activity;
  7. 7 import android.os.Bundle;
  8. 8 import android.view.View;
  9. 9 import android.widget.AdapterView;
  10. 10 import android.widget.AdapterView.OnItemSelectedListener;
  11. 11 import android.widget.ArrayAdapter;
  12. 12 import android.widget.Spinner;
  13. 13 import android.widget.Toast;
  14. 14
  15. 15 public class SpinnerBaseActivity extends Activity {
  16. 16 private Spinner spinner1, spinner2;
  17. 17
  18. 18 @Override
  19. 19 protected void onCreate(Bundle savedInstanceState) {
  20. 20 super.onCreate(savedInstanceState);
  21. 21 setContentView(R.layout.activity_spinnerbase);
  22. 22
  23. 23 spinner1 = (Spinner) findViewById(R.id.spinnerBase);
  24. 24 spinner2 = (Spinner) findViewById(R.id.spinnerBase1);
  25. 25 // 声明一个ArrayAdapter用于存放简单数据
  26. 26 ArrayAdapter<String> adapter = new ArrayAdapter<String>(
  27. 27 SpinnerBaseActivity.this, android.R.layout.simple_spinner_item,
  28. 28 getData());
  29. 29 // 把定义好的Adapter设定到spinner中
  30. 30 spinner1.setAdapter(adapter);
  31. 31 spinner2.setAdapter(adapter);
  32. 32 // 为第一个Spinner设定选中事件
  33. 33 spinner1.setOnItemSelectedListener(new OnItemSelectedListener() {
  34. 34
  35. 35 @Override
  36. 36 public void onItemSelected(AdapterView<?> parent, View view,
  37. 37 int position, long id) {
  38. 38 // 在选中之后触发
  39. 39 Toast.makeText(SpinnerBaseActivity.this,
  40. 40 parent.getItemAtPosition(position).toString(),
  41. 41 Toast.LENGTH_SHORT).show();
  42. 42 }
  43. 43
  44. 44 @Override
  45. 45 public void onNothingSelected(AdapterView<?> parent) {
  46. 46 // 这个一直没有触发,我也不知道什么时候被触发。
  47. 47 //在官方的文档上说明,为back的时候触发,但是无效,可能需要特定的场景
  48. 48 }
  49. 49 });
  50. 50
  51. 51 }
  52. 52
  53. 53 private List<String> getData() {
  54. 54 // 数据源
  55. 55 List<String> dataList = new ArrayList<String>();
  56. 56 dataList.add("北京");
  57. 57 dataList.add("上海");
  58. 58 dataList.add("南京");
  59. 59 dataList.add("宜昌");
  60. 60 return dataList;
  61. 61 }
  62. 62
  63. 63 }

XML资源文件:

  1. 1 <?xml version="1.0" encoding="utf-8"?>
  2. 2 <resources>
  3. 3 <string name="app_name">SpinnerDemo</string>
  4. 4 <string name="action_settings">Settings</string>
  5. 5 <string name="hello_world">Hello world!</string>
  6. 6 <string name="beij_prompt">北京区域</string>
  7. 7 <string-array name="beijing">
  8. 8 <item>朝阳区</item>
  9. 9 <item>海淀区</item>
  10. 10 <item>房山区</item>
  11. 11 <item>丰台区</item>
  12. 12 <item>东城区</item>
  13. 13 <item>西城区</item>
  14. 14 </string-array>
  15. 15 </resources>

效果展示,图片顺序,从上到下:

  

SimpleAdapter配置Spinner数据

对于一个稍复杂的数据,如果想对其展示,光使用ArrayAdapter是无法满足需求的,现在在另外介绍一个Adapter, SimpleAdapter ,同样继承自Adapter。

SimpleAdapter是一个简单的适配器,映射静态的XML格式的布局文件到视图中。可以指定一个List<Map<P,T>>格式的数据,List中的每一条数据对应一行,而Map中的每一条数据对应数据行的一列。这个数据用来映射到XML定义的布局控件中,对应关系通过构造函数的另外两个参数来指定,现在来介绍一下SimpleAdapter的构造函数。

SimpleAdapter(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to)

  • context:上下文对象,没什么好说的,一般就是当前的Activity。
  • data:上面介绍的List<Map<S,T>>类型的数据。
  • resource:XML资源的Id,通过R对象选中。
  • from:一个String类型数组,每条数据对应data数据中,Map结构定义的Key。
  • to:一个int类型数组,对应XML资源中控件的ID,注意顺序必须与from中指定数据的顺序一致。

下面通过一个示例讲解一下SimpleAdapter是如何设置自定义格式数据的。

布局代码:

  1. 1 <?xml version="1.0" encoding="utf-8"?>
  2. 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. 3 android:layout_width="match_parent"
  4. 4 android:layout_height="match_parent"
  5. 5 android:orientation="vertical" >
  6. 6
  7. 7 <Spinner android:id="@+id/spinnerAdapter" android:layout_width="match_parent"
  8. 8 android:layout_height="wrap_content" />
  9. 9 </LinearLayout>

XML布局资源代码:

  1. 1 <?xml version="1.0" encoding="utf-8"?>
  2. 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. 3 android:layout_width="match_parent"
  4. 4 android:layout_height="wrap_content"
  5. 5 android:orientation="horizontal" >
  6. 6
  7. 7 <ImageView
  8. 8 android:id="@+id/imageview"
  9. 9 android:layout_width="60dp"
  10. 10 android:layout_height="60dp"
  11. 11 android:paddingLeft="10dp"
  12. 12 android:src="@drawable/ic_launcher" />
  13. 13
  14. 14 <TextView
  15. 15 android:id="@+id/textview"
  16. 16 android:layout_width="match_parent"
  17. 17 android:layout_height="wrap_content"
  18. 18 android:gravity="center_vertical"
  19. 19 android:paddingLeft="10dp"
  20. 20 android:textColor="#000"
  21. 21 android:textSize="16dp" />
  22. 22
  23. 23 </LinearLayout>

实现代码:

  1. 1 package com.bgxt.datatimepickerdemo;
  2. 2
  3. 3 import java.util.ArrayList;
  4. 4 import java.util.HashMap;
  5. 5 import java.util.List;
  6. 6 import java.util.Map;
  7. 7
  8. 8 import android.app.Activity;
  9. 9 import android.os.Bundle;
  10. 10 import android.view.View;
  11. 11 import android.widget.AdapterView;
  12. 12
  13. 13 import android.widget.AdapterView.OnItemSelectedListener;
  14. 14 import android.widget.SimpleAdapter;
  15. 15 import android.widget.Spinner;
  16. 16 import android.widget.Toast;
  17. 17
  18. 18 public class SpinnerAdapterActivity extends Activity {
  19. 19 private Spinner spinner;
  20. 20
  21. 21 @Override
  22. 22 protected void onCreate(Bundle savedInstanceState) {
  23. 23 // TODO Auto-generated method stub
  24. 24 super.onCreate(savedInstanceState);
  25. 25 setContentView(R.layout.activity_spinneradapter);
  26. 26
  27. 27 spinner = (Spinner) findViewById(R.id.spinnerAdapter);
  28. 28 //声明一个SimpleAdapter独享,设置数据与对应关系
  29. 29 SimpleAdapter simpleAdapter = new SimpleAdapter(
  30. 30 SpinnerAdapterActivity.this, getData(), R.layout.items,
  31. 31 new String[] { "ivLogo", "applicationName" }, new int[] {
  32. 32 R.id.imageview, R.id.textview });
  33. 33 //绑定Adapter到Spinner中
  34. 34 spinner.setAdapter(simpleAdapter);
  35. 35 //Spinner被选中事件绑定。
  36. 36 spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
  37. 37
  38. 38 @Override
  39. 39 public void onItemSelected(AdapterView<?> parent, View view,
  40. 40 int position, long id) {
  41. 41 //parent为一个Map结构的和数据
  42. 42 Map<String, Object> map = (Map<String, Object>) parent
  43. 43 .getItemAtPosition(position);
  44. 44 Toast.makeText(SpinnerAdapterActivity.this,
  45. 45 map.get("applicationName").toString(),
  46. 46 Toast.LENGTH_SHORT).show();
  47. 47 }
  48. 48
  49. 49 @Override
  50. 50 public void onNothingSelected(AdapterView<?> arg0) {
  51. 51
  52. 52 }
  53. 53 });
  54. 54 }
  55. 55
  56. 56 public List<Map<String, Object>> getData() {
  57. 57 //生成数据源
  58. 58 List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
  59. 59 //每个Map结构为一条数据,key与Adapter中定义的String数组中定义的一一对应。
  60. 60 Map<String, Object> map = new HashMap<String, Object>();
  61. 61 map.put("ivLogo", R.drawable.bmp1);
  62. 62 map.put("applicationName", "表情1");
  63. 63 list.add(map);
  64. 64 Map<String, Object> map2 = new HashMap<String, Object>();
  65. 65 map2.put("ivLogo", R.drawable.bmp2);
  66. 66 map2.put("applicationName", "表情2");
  67. 67 list.add(map2);
  68. 68 Map<String, Object> map3 = new HashMap<String, Object>();
  69. 69 map3.put("ivLogo", R.drawable.bmp3);
  70. 70 map3.put("applicationName", "表情3");
  71. 71 list.add(map3);
  72. 72 return list;
  73. 73 }
  74. 74 }

效果展示:

 

源码下载

请支持原创,尊重原创,转载请注明出处。谢谢。

Android--UI之Spinner的更多相关文章

  1. Android UI自定义Spinner下拉框(用popuwindow实现)-转

    定义出第一个图片的布局和弹出框(一个listView)的布局,,这里就不在多说了~ListView需要自己定义一个MyspinnerAdapter~做好这些准备之后,就是弹出框的实现了~  prote ...

  2. Android UI基础教程 目录

    从csdn下载了这本英文版的书之后,又去京东搞了一个中文目录下来.对照着看. 话说,这本书绝对超值.有money的童鞋看完英文版记得去买中文版的~~ Android UI基础教程完整英文版 pdf+源 ...

  3. 【转】【Android UI设计与开发】之详解ActionBar的使用,androidactionbar

    原文网址:http://www.bkjia.com/Androidjc/895966.html [Android UI设计与开发]之详解ActionBar的使用,androidactionbar 详解 ...

  4. GitHub上受欢迎的Android UI Library

    GitHub上受欢迎的Android UI Library 内容 抽屉菜单 ListView WebView SwitchButton 按钮 点赞按钮 进度条 TabLayout 图标 下拉刷新 Vi ...

  5. 腾讯出品的一个超棒的 Android UI 库

    腾讯出品的一个超棒的 Android UI 库 相信做 Android 久了大家都会有种体会,那就是 Android 开发相对于前端开发来说统一的 UI 开源库比较少.造成这种现象的原因一方面是大多数 ...

  6. Android UI相关开源项目库汇总

    最近做了一个Android UI相关开源项目库汇总,里面集合了OpenDigg 上的优质的Android开源项目库,方便移动开发人员便捷的找到自己需要的项目工具等,感兴趣的可以到GitHub上给个st ...

  7. iPhone/iPad/Android UI尺寸规范 UI尺寸规范,UI图标尺寸,UI界面尺寸,iPhone6尺寸,iPhone6 Plus尺寸,安卓尺寸,iOS尺寸

    iPhone/iPad/Android UI尺寸规范 UI尺寸规范,UI图标尺寸,UI界面尺寸,iPhone6尺寸,iPhone6 Plus尺寸,安卓尺寸,iOS尺寸 iPhone界面尺寸 设备 分辨 ...

  8. Android ui 测试课堂笔记

    开始接触Android ui测试了,笔记如下 模拟器 Genemotion , the fastest android simulator in the world Android ui 测试工具 S ...

  9. Android UI 绘制过程浅析(五)自定义View

    前言 这已经是Android UI 绘制过程浅析系列文章的第五篇了,不出意外的话也是最后一篇.再次声明一下,这一系列文章,是我在拜读了csdn大牛郭霖的博客文章<带你一步步深入了解View> ...

  10. 12套有用的免费 PSD 格式 Android UI 素材

    在这里,我们向大家呈现一些有用的和免费的 Android 用户界面 PSD 素材.由于 Android 市场迅速增长,设计人员和开发人员正在寻找一些快速和容易的方法来创建 Android 友好的应用和 ...

随机推荐

  1. java1.8常用的函数式接口

    //常用函数式接口 final ; //num++; //第一个为传入参数的类型:第二个为返回数据的类型 Function<int[],String> function = (from) ...

  2. 第1章 Linux系统简介

    第1节 UNIX发展历史和发行版本 1. UNIX与Linux发展史 1.1 UNIX发展历史 (1)1965年,美国麻省理工学院(MIT).通用电气公司(GE)及AT&T的贝尔实验室联合开发 ...

  3. java之多线程 一

    概述: 几乎任何的操作系统都支持运行多个任务,通常一个任务就是一个程序,而一个程序就是一个进程.当一个进程运行时,内部可能包括多个顺序执行流,每个顺序执行流就是一个线程. 进程与线程: 进程是指处于运 ...

  4. Markdown 11种基本语法

    markdown真的很方便! 我根据自己在github上维护的项目编写的readme文件总结一些最基本的使用方法 ,学完这些Markdown的基本使用已经不成问题. 1. 标题设置(让字体变大,和wo ...

  5. 栈的理解以及如何计算程序所需栈的大小并在IAR中设置栈

    文章首发于浩瀚先森博客 #栈的理解 一个程序大体上讲都是由变量和函数组合而成,变量有全局变量和局部变量,还有函数间传值的参数以及返回值. Stack是为了程序运行过程中临时保存所需数据而在内存里分配的 ...

  6. EF6 在 SQLite中使用备忘

    == 菜鸟级选手试验在EF6中使用Sqlite,零EF基础,少量Sqlite基础.经过断断续续的很长时间 - _ -! >>连接 1. 安装 使用目前最新版本EF6.1,Sqlite1.0 ...

  7. Gson解析json字符串

    // 解析传递过来的json字符串 JsonParser parser = new JsonParser(); JsonObject jsonObj = parser.parse(strJson).g ...

  8. Learning to rank 介绍

    PS:文章主要转载自CSDN大神hguisu的文章"机器学习排序":          http://blog.csdn.net/hguisu/article/details/79 ...

  9. js 获取时间间隔

    现在感觉sublime   IDE 用着比较方便,也比较美观,不知道大家用的是啥ide.

  10. 87 resize2fs-增大或者收缩未加载的“ext2/ext3”文件系统的大小

    resize2fs命令被用来增大或者收缩未加载的"ext2/ext3"文件系统的大小.如果文件系统是处于mount状态下,那么它只能做到扩容,前提条件是内核支持在线resize., ...