Android Spinner 控件 详解 - 泡 在 网上 的 日子

Spinner 提供 了 从 一个 数据 集合 中 快速 选择 一项 值 的 办法. 默认 情况 下 Spinner 显示 的 是 当前 选择 的 值, 点击 Spinner 会 弹出 一个 包含 所有 可选 值 的 dropdown 菜单, 从 该 菜单 中 可以 为 Spinner 选择一个 新 值.

spinner.png

是 图 显示 的 是 Spinner 常见 的 样式. 这篇 文章 中 我 将 讨论 1.Spinner 的 基本 用法 2. 设置 Spinner 的 Adapter (arrayadapter 和 自 定义 BaseAdapter) 3.Spinner 的 菜单 显示 方式 4.Spinner 的 xml 属性

最 简单 的 Spinner

在 布局 文件 中 添加 Spinner 控件

 <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <Spinner android:id="@+id/spinner1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:entries="@array/languages" /> </LinearLayout>

其中 Android: entries = "@ matrice / languages" 表示 Spinner 的 数据 集合 是 从 资源 数组 lingue 中 获取 的, lingue 数组 资源 定义 在 valori / arrays.xml 中:

<?xml version="1.0" encoding="utf-8"?><resources> <string-array name="languages"> <item>c语言</item> <item>java </item> <item>php</item> <item>xml</item> <item>html</item> </string-array></resources>

如果 你 不需要 对 Spinner 的 选择 事件 做 响应, 那么 一个 完整 的 Spinner 使用 流程 就 结束 了.

运行结果:

QQ 图片 20150105013559.jpg

当然, 一般 情况 下 我们 是 需要 响应 Spinner 选择 事件 的, 可以 通过 OnItemSelectedListener 的 回调 方法 实现

la classe pubblica MainActivity estende l'attività { @Oltrepassare protected void onCreate (Bundle savedInstanceState) { super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); Spinner spinner = (Spinner) findViewById (R.id.spinner1); spinner.setOnItemSelectedListener (new OnItemSelectedListener () { @Oltrepassare public void onItemSelected (AdapterView <?> parent, View view, int pos, long id) { String [] languages ​​= getResources (). GetStringArray (R.array.languages); Toast.makeText (MainActivity.this, "你 点击 的 是:" + languages ​​[pos], 2000) .show (); } @Oltrepassare public void onNothingSelected (AdapterView <?> parent) { // Un'altra callback dell'interfaccia } }); } }

上面 的 Spinner 看起来 非常 漂亮, 不过 它 并不是 总是 如此, 刚刚 看到 的 是 在 Android: Theme.Holo.Light 主题 下 的 效果, 同样 的 代码 如果 在 Android: Theme.Light 下面 就会 变得 很丑.


想必 这 也是 很多 人 不想 使用 Spinner 的 原因 了 吧. 如果 想 兼容 2.3, 则 只能 忍受 这样 的 效果.

设置 adattatore 的 Spinner

上面 使用 Spinner 数据 源于 xml 数组, 其实 用 的 最多 的 还是 通过 adattatore 来 跟 Spinner 绑定 数据.

使用 ArrayAdapter

// 初始化 控件Spinner spinner = (Spinner) findViewById (R.id.spinner1);// 建立 数据 源String [] mItems = getResources (). GetStringArray (R.array.languages);// 建立 Adattatore 并且 绑定 数据 源ArrayAdapter <String> adapter = new ArrayAdapter <String> (questo, android.R.layout.simple_spinner_item, mItems);adapter.setDropDownViewResource (android.R.layout.simple_spinner_dropdown_item);// 绑定 Adattatore 到 控件spinner .setAdapter (adattatore);spinner.setOnItemSelectedListener (new OnItemSelectedListener () { @Oltrepassare public void onItemSelected (AdapterView <?> parent, View view, int pos, long id) { String [] languages ​​= getResources (). GetStringArray (R.array.languages); Toast.makeText (MainActivity.this, "你 点击 的 是:" + languages ​​[pos], 2000) .show (); } @Oltrepassare public void onNothingSelected (AdapterView <?> parent) { // Un'altra callback dell'interfaccia }});

这 是 Spinner 的 标准 使用 方法, 其中, 有 两 行 代码 可以 决定 Spinner 的 外观:

1

ArrayAdapter <String> adapter = new ArrayAdapter <String> (questo, android.R.layout.simple_spinner_item, mItems);

第二 个 参数 是 Spinner 未 展开 菜单 时 Spinner 的 默认 样式, android.R.layout.simple_spinner_item 是 系统 自带 的 内置 布局.

2

adapter.setDropDownViewResource (android.R.layout.simple_spinner_dropdown_item);

设置 的 是 展开 的 时候 下拉 菜单 的 样式 (注意 和 上面 区别), 同理 android.R.layout.simple_spinner_dropdown_item 也是 内置 布局.

如果 不 设置 adapter.setDropDownViewResource (android.R.layout.simple_spinner_dropdown_item) 会 怎样 呢?

. 会 造成 未 展开 的 sipnner 和 展开 的 菜单 都是 一种 布局 样式 下面 一 运行 截图 来 说明:

没有 adapter.setDropDownViewResource (android.R.layout.simple_spinner_dropdown_item):

QQ 图片 20150105161936.jpg

有 setDropDownViewResource:

QQ 图片 20150105162135.jpg

D 可能 会 很 好奇 如果 了 setDropDownViewResource 但是 setDropDownViewResource 的 参数 和 ArrayAdapter 的 第二 个 布局 参数 (simple_spinner_item) 一致 的 情况 下 会 怎样. 情况 是 和 没有 setDropDownViewResource 是 一样 的, 因为 上面 说 不 设置 setDropDownViewResource Spinner 未 展开和 展开 都是 用 的 一样 的 布局.

其实 simple_spinner_item 和 simple_spinner_dropdown_item 两者 的 名字 正好 反映 了 他们 的 区别. 一个 应用于 下拉 一个 应用于 Spinner 本身.

使用 自 定义 的 BaseAdapter

这种 情况 适用 于 filatore 比较 复杂 的 情况, 比如 带有 图标.

下面 我们 定义 一个 选择 联系人 的 Spinner.

 <LinearLayout android:layout_width="fill_parent" android:layout_height="80dip" android:orientation="vertical" > <Spinner android:id="@+id/spinner2" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>

Attività 中:

 // 初始化 控件 Spinner spinner2 = (Spinner) findViewById (R.id.spinner2); // 建立 数据 源 Elenco <Person> persons = new ArrayList <Person> (); persons.add (new Person ("张三", "上海")); persons.add (new Person ("李四", "上海")); person.add (new Person ("王 五", "北京")); person.add (new Person ("赵 六", "广州")); // 建立 Adattatore 绑定 数据 源 MyAdapter _MyAdapter = new MyAdapter (this, persons); // 绑定 Adapter spinner2.setAdapter (_MyAdapter);

Person.java

pacchetto com.example.spinnerdemo; persona di classe pubblica { private String personName; private String personAddress; persona pubblica (String personName, String personAddress) { super(); this.personName = personName; this.personAddress = personAddress; } public String getPersonName () { return personName; } public void setPersonName (String personName) { this.personName = personName; } public String getPersonAddress () { return personAddress; } public void setPersonAddress (String personAddress) { this.personAddress = personAddress; } }

MyAdapter.java

pacchetto com.example.spinnerdemo;import java.util.List;importare android.content.Context;import android.view.LayoutInflater;importa android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ImageView;import android.widget.TextView; / ** * 自 定义 适配器 类 * @author jiangqq <a href=http://blog.csdn.net/jiangqq781931404> </a> * * /La classe pubblica MyAdapter estende BaseAdapter { Elenco privato <Persona> mLista; contesto privato mContext; MyAdapter pubblico (Contesto pContext, Elenco <Person> pList) { this.mContext = pContext; this.mList = pList; } @Oltrepassare public int getCount () { return mList.size (); } @Oltrepassare oggetto pubblico getItem (int position) { return mList.get (posizione); } @Oltrepassare public long getItemId (int position) { posizione di ritorno; } / ** * 下面 是 重要 代码 * / @Oltrepassare public View getView (int position, Visualizza convertView, ViewGroup parent) { LayoutInflater _LayoutInflater = LayoutInflater.from (mContext); convertView = _LayoutInflater.inflate (R.layout.item_custom, null); if (convertView! = null) { ImageView imageView = (ImageView) convertView.findViewById (R.id.image); imageView.setImageResource (R.drawable.ic_launcher); TextView _TextView1 = (TextView) convertView.findViewById (R.id.textView1); TextView _TextView2 = (TextView) convertView.findViewById (R.id.textView2); _TextView1.setText (mList.get (posizione) .getPersonName ()); _TextView2.setText (mList.get (posizione) .getPersonAddress ()); } return convertView; }}

运行效果:

QQ 图片 20150105170110.png

Spinner 的 菜单 显示 方式

它 有 两种 显示 形式, 一种 是 下拉 菜单, 一种 是 弹出 框, 菜单 显示 形式 是 spinnerMode 属性 决定 的:

Android: spinnerMode = "discesa"Android: spinnerMode = "finestra"

在 Android2.3 上 没有 这个 属性, 系统 默认 将 Spinner 弹出 菜单 显示 成 dialogo. 下面 是 和 Theme.Light Theme.Holo.Light 下 Spinner 在 不同 模式 下 的 效果 对比 图.


cadere in picchiata dialogo

Theme.Light

默认为弹出框的形式


Theme.Holo.Light

默认为下拉菜单的形式

Spinner 的 xml 属性

其实 上面 已经 提到 了 Spinner 的 两个 属性:

1 voci: 直接 在 xml 布局 文件 中 绑定 数据 源 (可以 不 设置, 即 可以 在 Attività 中 动态 绑定)

2 spinnerMode: Spinner 的 显示 形式

除此之外还有如下属性:

chiederà: 在 Spinner 弹出 选择 对话框 的 时候 对话框 的 标题:

QQ 图片 20150105024315.jpg

属性名称

Android: dropDownHorizontalOffset

对应方法:

setDropDownHorizontalOffset (int)

spinnerMode =”discesa” 时, 下拉 的 项目 选择 窗口 在 水平 方向 相 对于 Spinner 窗口 的 偏移 量.

它 必须 是 一个 带有 单位 的 浮点 型 尺寸 值, 如:”14.5sp” 有效 的 单位 包括:. Px (像素), dp (密度 无关 的 像素), sp (基于 引用 字体 的 尺寸 来 缩放 的 像素), in (英寸), mm (毫米).

这个 属性 还 可以引用 一个 资源 (格式: @ [package:] tipo: nome) 或者 是 包含 这种 类型 值 的 主题 属性 (格式:? [Pacchetto] [Tipo:] nome).

这个 属性 对应 全局 属性 资源 符号 dropDownHorizontalOffset.

Android: dropDownSelector

用于 设定 spinnerMode =”discesa” 时 列表 选择 器 的 显示 效果.

它 可以 用 "@ [+] [pacchetto]: tipo: nome" 格式 来 引用 另外 的 资源, 或者 是 用 "? [Pacchetto:] [tipo:] nome" 的 格式 来 应用 主题 属性, 还 可以 是 "# RGB”,” # ARGB”,” # rrggbb”,” aarrggbb”格式 的 颜色 值.

它 对应 的 全局 属性 资源 符号 是 dropDownSelector.

Android: dropDownVerticalOffset

对应方法:

setDropDownVerticalOffset (int)

spinnerMode =”discesa” 时, 下拉 的 项目 选择 窗口 在 垂直 方向 相 对于 Spinner 窗口 的 偏移 量.

这个 属性 它 必须 是 一个 带有 单位 的 浮点 型 尺寸 值, 如:”14.5sp” 有效 的 单位 包括:. Px (像素), dp (密度 无关 的 像素), sp (基于 引用 字体 的 尺寸 来 缩放的 像素), a (英寸), mm (毫米).

还 可以引用 一个 资源 (格式: @ [package:] tipo: nome) 或者 是 包含 这种 类型 值 的 主题 属性 (格式:? [Pacchetto] [Tipo:] nome).

这个 属性 对应 全局 属性 资源 符号 dropDownVerticalOffset.

Android: dropdownWidth

对应方法:

setDropDownWidth (int)

在 spinnerMode =”discesa” 时, 设定 下拉 框 的 宽度.

这个 属性 可以 是 带有 单位 的 浮点 型 的 尺寸 值, 如:. 14.5sp 有效 的 单位 包括: px (像素), dp (密度 无关 的 像素), sp (基于 引用 字体 的 尺寸 来 缩放 的 像素) , in (英寸), mm (毫米).

还 可以引用 一个 资源 (格式: @ [package:] tipo: nome) 或者 是 包含 这种 类型 值 的 主题 属性 (格式:? [Pacchetto] [Tipo:] nome).

还可以是下列常量之一:

fill_parent = -1, 下拉 框 的 宽度 应该 使用 的 的 宽度 来 设定. 这个 常量 从 Livello API 8 开始 被 废弃 了, 并且 使用 mach_parent 常量 来 代替.

mach_parent = -1, 下拉 框 的 宽度 应该 使用 屏幕 的 宽度 来 设定. 在 Livello API 8 中 被 引入.

wrap_content = -2, 下拉 框 的 宽度 应该 跟它 的 内容 相 适应.

它 对应 的 全局 资源 符号 是 dropdownWidth.

Android: la gravità

对应方法:

setGravity (int)

这个属性用于设置当前选择的项目的对齐方式。

它必须是以下常量值之一或组合(用”|”符号分离)。

top = 0x30: 把 选择 的 对象 放到 它 的 容器 的 顶部, 不 改变 它 的 尺寸.

bottom = 0x50: 把 选择 的 对象 放到 它 的 容器 的 底部, 不 改变 它 的 尺寸.

sinistra = 0x03: 把 选择 的 对象 放到 它 的 容器 的 左边, 不 改变 它 的 尺寸.

destra = 0x05: 把 选择 的 对象 放到 它 的 容器 的 右边, 不 改变 它 的 尺寸.

center_vertical = 0x10: 把 选择 的 对象 放到 它 的 容器 的 垂直 中心, 不 改变 它 的 尺寸.

fill_vertical = 0x70: 为了 完全 的 填充 它 的 容器, 系统 会 根据 需要 来 增加 选择 的 的 垂直 尺寸.

center_horizontal = 0x01: 把 选择 的 对象 放到 它 的 容器 的 水平 中心, 不 改变 它 的 尺寸.

fill_horizontal = 0x07: 为了 完全 的 填充 它的 容器, 系统 会 根据 需要 来 增加 选择 对象 的 水平 尺寸.

center = 0x11: 把 选择 的 对象 放到 它 的 容器 的 垂直 和 水平 中心, 不 改变 它 的 尺寸.

fill = 0x77: 为了 完全 的 填充 它 的 容器, 系统 会 根据 需要 来 增加 选择 的 水平 和 垂直 尺寸.

clip_vertical = 0x80: 附加 的 可选 设置, 它 可以 设置 容器 内 的 的 上下 边缘 边缘 的 的 方式 顶部: 顶部 对齐 的 会 裁剪 边缘 边缘, 底部 对齐 的 会 裁剪 顶部 边缘, 不会上 下 边缘 都 裁剪.

clip_horizontal = 0x08: 附加 的 可选 设置, 它 可以 设置 容器 内 的 的 左右 边缘 边缘 边缘 的 方式 左: 左 对齐 的 会 裁剪 边缘 边缘, 右 对齐 的 会 裁剪 左 边缘, 不会 左右 边缘 都 裁剪.

start = 0x00800003: 把 对象 放到 它 的 容器 的 开始 位置, 不 改变 它 的 尺寸.

fine = 0x00800005: 把 对象 放到 它 的 容器 的 结束 位置, 不 改变 它 的 尺寸.

对应 的 全局 属性 资源 符号 是 gravità.

注: Spinner 对象 是 一个 视窗 对象 容器, 设置 它 的 gravità 属性 时, 只会 改变 容器 内部 子 视窗 对象 的 对齐 方式, 并 不会 改变 子 视窗 内部 内容 的 对齐 方式.

Android: popupBackground

对应方法:

setPopupBackgroundResource (int)

在 filatore =”discesa” 时, 使用 这个 属性 来 设置 下拉 列表 的 背景.

可以 使用 "@ [+] [pacchetto:] tipo: nome" 格式 来 引用 另外 的 资源, 或者 使用 "? [Pacchetto:] [tipo:] nome" 格式 来 应 用 主题 属性, 也 可以 使用 "#rgb" ,”# ARGB”,”# rrggbb”,”# aarrggbb” 格式 的 颜色 值.

对应 的 全局 属性 资源 符号 是 popupBackground

打赏

1451035740457944.jpg

4.4
5
13
4
4
3
2
2
2
1
1