前言
最近一直在講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 <?xml version="1.0" encoding="utf-8"?>
2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 android:layout_width="match_parent"
4 android:layout_height="match_parent"
5 android:orientation="vertical" >
6
7 <TextView
8 android:layout_width="wrap_content"
9 android:layout_height="wrap_content"
10 android:text="彈出的Spinner" />
11
12 <Spinner
13 android:id="@+id/spinnerBase"
14 android:layout_width="match_parent"
15 android:layout_height="wrap_content"
16 android:spinnerMode="dialog" />
17
18 <TextView
19 android:layout_width="wrap_content"
20 android:layout_height="wrap_content"
21 android:text="下拉的Spinner(預設)" />
22
23 <Spinner
24 android:id="@+id/spinnerBase1"
25 android:layout_width="match_parent"
26 android:layout_height="wrap_content"
27 android:spinnerMode="dropdown" />
28
29 <TextView
30 android:layout_width="wrap_content"
31 android:layout_height="wrap_content"
32 android:text="entries綁定資料源" />
33
34 <Spinner
35 android:id="@+id/spinnerBase2"
36 android:layout_width="match_parent"
37 android:layout_height="wrap_content"
38 android:entries="@array/beijing" />
39
40 <TextView
41 android:layout_width="wrap_content"
42 android:layout_height="wrap_content"
43 android:text="彈出帶标題的Dialog,并且使用entries綁定資料源" />
44
45 <Spinner
46 android:id="@+id/spinnerBase3"
47 android:layout_width="match_parent"
48 android:layout_height="wrap_content"
49 android:entries="@array/beijing"
50 android:prompt="@string/beij_prompt"
51 android:spinnerMode="dialog" />
52
53 </LinearLayout>
實作代碼:
1 package com.bgxt.datatimepickerdemo;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
6 import android.app.Activity;
7 import android.os.Bundle;
8 import android.view.View;
9 import android.widget.AdapterView;
10 import android.widget.AdapterView.OnItemSelectedListener;
11 import android.widget.ArrayAdapter;
12 import android.widget.Spinner;
13 import android.widget.Toast;
14
15 public class SpinnerBaseActivity extends Activity {
16 private Spinner spinner1, spinner2;
17
18 @Override
19 protected void onCreate(Bundle savedInstanceState) {
20 super.onCreate(savedInstanceState);
21 setContentView(R.layout.activity_spinnerbase);
22
23 spinner1 = (Spinner) findViewById(R.id.spinnerBase);
24 spinner2 = (Spinner) findViewById(R.id.spinnerBase1);
25 // 聲明一個ArrayAdapter用于存放簡單資料
26 ArrayAdapter<String> adapter = new ArrayAdapter<String>(
27 SpinnerBaseActivity.this, android.R.layout.simple_spinner_item,
28 getData());
29 // 把定義好的Adapter設定到spinner中
30 spinner1.setAdapter(adapter);
31 spinner2.setAdapter(adapter);
32 // 為第一個Spinner設定選中事件
33 spinner1.setOnItemSelectedListener(new OnItemSelectedListener() {
34
35 @Override
36 public void onItemSelected(AdapterView<?> parent, View view,
37 int position, long id) {
38 // 在選中之後觸發
39 Toast.makeText(SpinnerBaseActivity.this,
40 parent.getItemAtPosition(position).toString(),
41 Toast.LENGTH_SHORT).show();
42 }
43
44 @Override
45 public void onNothingSelected(AdapterView<?> parent) {
46 // 這個一直沒有觸發,我也不知道什麼時候被觸發。
47 //在官方的文檔上說明,為back的時候觸發,但是無效,可能需要特定的場景
48 }
49 });
50
51 }
52
53 private List<String> getData() {
54 // 資料源
55 List<String> dataList = new ArrayList<String>();
56 dataList.add("北京");
57 dataList.add("上海");
58 dataList.add("南京");
59 dataList.add("宜昌");
60 return dataList;
61 }
62
63 }
XML資源檔案:
1 <?xml version="1.0" encoding="utf-8"?>
2 <resources>
3 <string name="app_name">SpinnerDemo</string>
4 <string name="action_settings">Settings</string>
5 <string name="hello_world">Hello world!</string>
6 <string name="beij_prompt">北京區域</string>
7 <string-array name="beijing">
8 <item>朝陽區</item>
9 <item>海澱區</item>
10 <item>房山區</item>
11 <item>豐台區</item>
12 <item>東城區</item>
13 <item>西城區</item>
14 </string-array>
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 <?xml version="1.0" encoding="utf-8"?>
2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 android:layout_width="match_parent"
4 android:layout_height="match_parent"
5 android:orientation="vertical" >
6
7 <Spinner android:id="@+id/spinnerAdapter" android:layout_width="match_parent"
8 android:layout_height="wrap_content" />
9 </LinearLayout>
XML布局資源代碼:
1 <?xml version="1.0" encoding="utf-8"?>
2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 android:layout_width="match_parent"
4 android:layout_height="wrap_content"
5 android:orientation="horizontal" >
6
7 <ImageView
8 android:id="@+id/imageview"
9 android:layout_width="60dp"
10 android:layout_height="60dp"
11 android:paddingLeft="10dp"
12 android:src="@drawable/ic_launcher" />
13
14 <TextView
15 android:id="@+id/textview"
16 android:layout_width="match_parent"
17 android:layout_height="wrap_content"
18 android:gravity="center_vertical"
19 android:paddingLeft="10dp"
20 android:textColor="#000"
21 android:textSize="16dp" />
22
23 </LinearLayout>
實作代碼:
1 package com.bgxt.datatimepickerdemo;
2
3 import java.util.ArrayList;
4 import java.util.HashMap;
5 import java.util.List;
6 import java.util.Map;
7
8 import android.app.Activity;
9 import android.os.Bundle;
10 import android.view.View;
11 import android.widget.AdapterView;
12
13 import android.widget.AdapterView.OnItemSelectedListener;
14 import android.widget.SimpleAdapter;
15 import android.widget.Spinner;
16 import android.widget.Toast;
17
18 public class SpinnerAdapterActivity extends Activity {
19 private Spinner spinner;
20
21 @Override
22 protected void onCreate(Bundle savedInstanceState) {
23 // TODO Auto-generated method stub
24 super.onCreate(savedInstanceState);
25 setContentView(R.layout.activity_spinneradapter);
26
27 spinner = (Spinner) findViewById(R.id.spinnerAdapter);
28 //聲明一個SimpleAdapter獨享,設定資料與對應關系
29 SimpleAdapter simpleAdapter = new SimpleAdapter(
30 SpinnerAdapterActivity.this, getData(), R.layout.items,
31 new String[] { "ivLogo", "applicationName" }, new int[] {
32 R.id.imageview, R.id.textview });
33 //綁定Adapter到Spinner中
34 spinner.setAdapter(simpleAdapter);
35 //Spinner被選中事件綁定。
36 spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
37
38 @Override
39 public void onItemSelected(AdapterView<?> parent, View view,
40 int position, long id) {
41 //parent為一個Map結構的和資料
42 Map<String, Object> map = (Map<String, Object>) parent
43 .getItemAtPosition(position);
44 Toast.makeText(SpinnerAdapterActivity.this,
45 map.get("applicationName").toString(),
46 Toast.LENGTH_SHORT).show();
47 }
48
49 @Override
50 public void onNothingSelected(AdapterView<?> arg0) {
51
52 }
53 });
54 }
55
56 public List<Map<String, Object>> getData() {
57 //生成資料源
58 List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
59 //每個Map結構為一條資料,key與Adapter中定義的String數組中定義的一一對應。
60 Map<String, Object> map = new HashMap<String, Object>();
61 map.put("ivLogo", R.drawable.bmp1);
62 map.put("applicationName", "表情1");
63 list.add(map);
64 Map<String, Object> map2 = new HashMap<String, Object>();
65 map2.put("ivLogo", R.drawable.bmp2);
66 map2.put("applicationName", "表情2");
67 list.add(map2);
68 Map<String, Object> map3 = new HashMap<String, Object>();
69 map3.put("ivLogo", R.drawable.bmp3);
70 map3.put("applicationName", "表情3");
71 list.add(map3);
72 return list;
73 }
74 }
效果展示:
源碼下載下傳
請支援原創,尊重原創,轉載請注明出處。謝謝。