天天看點

Android--UI之Spinner

前言

  最近一直在講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>      

  效果展示,圖檔順序,從上到下:

Android--UI之Spinner
Android--UI之Spinner
Android--UI之Spinner
Android--UI之Spinner
Android--UI之Spinner

 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 }      

   效果展示:

Android--UI之Spinner
Android--UI之Spinner

  源碼下載下傳

  請支援原創,尊重原創,轉載請注明出處。謝謝。