在Web開發中,HTML提供了下拉列表的實現,就是使用<select>元素實現一個下拉列表,在其中每個下拉列表項使用<option>表示即可。這是在Web開發中一個必不可少的交互性組件,在Android中的對應實現就是Spinner。
首先來看一下Spinner的文檔:
java.lang.Object
↳ android.view.View
↳ android.view.ViewGroup
↳ android.widget.AdapterView<T extends android.widget.Adapter>
↳ android.widget.AbsSpinner
↳ android.widget.Spinner
Spinner的繼承結構比較複雜,在繼承樹中有AdapterView,這是比較重要的一項,因爲我們就是通過Adapter來爲Spinner設置下拉列表項的。
Spinner的重點問題就是下拉列表項的配置,通過之前組件的瞭解,我們知道資源組件的配置有兩種方式,一種是通過XML文件來配置,一種是通過程序來配置。而從Spinner的文檔中,我們可以看到,對它的配置需要使用Adapter類的實現。
下面我們就來看看Spinner的使用,在Eclipse中創建SpinnerDemo項目,編寫代碼:
- <TextView
- android:id="@+id/degreeLabel"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="請選擇您的學歷" />
- <Spinner
- android:id="@+id/degree"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content" />
這裏放置了一個空的Spinner,直接運行程序,我們看到如下效果:
就是一個空的下拉框,什麼都沒有,下面我們開始向這個下拉框中設置列表項。首先我們使用XML資源文件的配置方式,在values目錄下創建spinner_data.xml,並設置如下內容:
- <string-array name="degrees">
- <item>初中及以下</item>
- <item>高中</item>
- <item>大學</item>
- <item>研究生及以上</item>
- </string-array>
不難理解<string-array>表示字符串的數組,就是可以定義多個字符串的項目,在其中,我們仍然使用<item>來定義每一項,設置好後,將其應用到Spinner中:
- <Spinner
- android:id="@+id/degree"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:entries="@array/degrees" />
配置Spinner組件中的entries屬性即可引用我們在spinner_data.xml中定義的degrees項目組了,不難想到,它已經被註冊到R.java中了。運行程序,我們得到如下顯示效果:
這裏可以看到,我們雖然設置了提示信息,但是點擊下拉框後並沒有出現Spinner的提示,而是直接顯示出了我們設置的選項,這樣的顯示並不是很好看,我們希望在彈出的Spinner選擇框上也給出提示,那麼我們可以這麼來設置:
- <Spinner
- android:id="@+id/degree"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:entries="@array/degrees"
- android:prompt="@string/degrees_prompt" />
也就是在Spinner組件中加上prompt屬性即可,注意這裏不能直接使用文本了,而需要使用引用,那麼我們在strings.xml中加入如下信息:
- <string name="degrees_prompt">您的學歷是:</string>
我們再次運行程序,就可以看到如下的效果:
這次再點擊Spinner,彈出的下拉框中就有了提示的prompt,顯示效果好了很多。
下面我們看看如何通過程序來控制Spinner和列表項,之前說過要使用程序,就要用到Adapter類,這裏我們使用實現類ArrayAdapter來進行操作。首先我們使用ArrayAdapter讀取XML配置文件的方式來說明:
- <string-array name="cities">
- <item>北京</item>
- <item>上海</item>
- <item>大連</item>
- </string-array>
我們在spinner_data.xml中再設置一組值來表示城市,有了列表項,我們還需要再創建一個Spinner,那麼在main.xml中,再設置一個Spinner:
- <TextView
- android:id="@+id/cityLabel"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="請選擇您所在的城市" />
- <Spinner
- android:id="@+id/city"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content" />
那麼在Activity程序中,我們可以如下來編寫代碼:
- package org.ourpioneer;
- import android.app.Activity;
- import android.os.Bundle;
- import android.widget.ArrayAdapter;
- import android.widget.Spinner;
- public class SpinnerDemoActivity extends Activity {
- private Spinner city = null;// 要讀取的下拉列表
- private ArrayAdapter<CharSequence> cities = null;// 要使用的Adapter
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- super.setContentView(R.layout.main);
- city = (Spinner) super.findViewById(R.id.city);// 獲取下拉列表
- city.setPrompt("您所在的城市是:");// 設置Prompt
- cities = ArrayAdapter.createFromResource(this, R.array.cities,android.R.layout.simple_spinner_item);// 實例化ArrayAdapter
- city.setAdapter(cities);// 設置顯示信息
- }
- }
根據代碼中的註釋,不難理解每行代碼的意思,這和在XML中配置Spinner是類似的。要多說的一點就是這裏我們爲ArrayAdapter設置的泛型是CharSequence,而不是直接使用String,這是出於以後對StringBuffer的兼容,來看下CharSequence的文檔:
不難看出,String和StringBuffer都是CharSequence的子類,這裏定義爲CharSequence後直接使用字符串格式是沒有問題的。
下面直接運行程序,我們可以看到如下效果:
此時列表項的顯示和之前的不同,是因爲我們在實例化ArrayAdapter時使用了android.R.layout.simple_spinner_item,也就是使用了簡單的spinner項。
可以通過如下的代碼控制顯示風格:
- cities.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);// 設置列表項的顯示風格
之後再次運行代碼,就可以看到和之前一樣的顯示效果了。
下面來看第二種ArrayAdapter的使用方式,就是在程序中動態生成結果來進行填充,我們修改上面的代碼,最終爲:
- package org.ourpioneer;
- import java.util.Arrays;
- import java.util.List;
- import android.app.Activity;
- import android.os.Bundle;
- import android.widget.ArrayAdapter;
- import android.widget.LinearLayout;
- import android.widget.Spinner;
- import android.widget.TextView;
- public class SpinnerDemoActivity extends Activity {
- // 省略City部分Spinner和ArrayAdapter聲明的代碼
- private Spinner age = null;// 聲明一個Spinner組件,表示年齡
- private ArrayAdapter<CharSequence> ages = null;// 聲明一個ArrayAdapter來適配年齡
- private List<CharSequence> age_data = null;// 聲明一個放置年齡數據的List
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- super.setContentView(R.layout.main);
- // 省略City部分的設置代碼
- age = new Spinner(this);// 創建Spinner對象
- age.setPrompt("您的年齡段是:");// 設置Prompt
- age_data = Arrays.asList(new CharSequence[] { "10歲以下", "10-20歲",
- "20-30歲", "30-40歲", "40-50歲", "50-60歲", "60歲以上" });// 設置年齡段數組並最終轉換爲List類型
- ages = new ArrayAdapter<CharSequence>(this,
- android.R.layout.simple_spinner_item, age_data);// 實例化ArrayAdapter
- ages.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);// 設置列表項顯示風格
- age.setAdapter(ages);// 設置顯示信息
- LinearLayout layout = (LinearLayout) super.findViewById(R.id.layout);
- TextView ageLabel=new TextView(this);
- ageLabel.setText("請選擇您的年齡段");
- layout.addView(ageLabel);
- layout.addView(age);
- }
- }
在此之前,不要忘了在main.xml中爲我們的佈局管理器加上ID屬性,這樣才能在程序中進行調用,運行程序,我們可以看到如下效果:
點擊即可彈出下拉列表框顯示具體內容了。
下面我們在Android設備上來運行Spinner的示例程序,運行環境爲Motorola Defy+ 2.3.7 MIUI,所得到的具體顯示效果爲:
可以看出,這和我們在模擬器中的顯示效果略有不同,那麼就是手機所刷ROM對我們組件顯示風格的影響了,也就是說,在不同的ROM下,會有不同的顯示效果。
本部分代碼請參考附件。