情境
如果你想要從一個集合內選出一個值,Spinner 是一個很好用的工具,它會提供一個下拉式選單, 顯示清單內所有的值讓使用者選擇。
例如:
午餐吃什麼?
有[雞腿飯、魯肉飯、排骨飯、水餃、陽春麵]這些選項提供使用者選擇,但是使用者只能選一個選項,這樣就是一個Spinner的應用了。
完整程式碼
如果需要參考完整程式碼,可以到以下網址參考。
程式碼 + 說明
建立一個Spinner有幾種方式。
方法一
你可以從程式碼內部直接建立,不需要在 XML 建立任何元件。
注意如果一開始你新建一個專案,記得將 xml內預設的TextView元件刪除,不然會出現TextView的Hello World。
下面的程式碼直接貼到 MainActivity.java 資料夾就可以執行了。
val spinner = Spinner(this)
container.addView(spinner)
container 是最外圍的 RelativeLayout,記得在 xml 上給它一個命名。
呈現效果如下圖。
你會發現只有一個向下的箭頭,原因是目前Spinner沒有任何清單集合的值,稍後我們會說明如何將值填入。
而對於程式碼建構元件是比較不推薦使用的方式,原因是從程式碼建構元件,當元件一多,會造成之後程式碼維護的困難度增加以及可讀性降低,比較好的方式是在XML上面進行宣告,所以後面的都會以方法二來進行編譯。
方法二
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin">
<Spinner
android:id="@+id/spinner"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
如下圖跟用程式宣告的效果是一樣的。
加入資料
前面提到 Spinner 需要加入資料才能跳出下拉式選單,在 Spinner 加入的資料的方法很多種。
加入資料 - 方法一
先在 res/strings
內加入一段程式碼。
<resources>
<string name="app_name">SpinnerDemo</string>
<string-array name="lunch">
<item>雞腿飯</item>
<item>魯肉飯</item>
<item>排骨飯</item>
<item>水餃</item>
<item>陽春麵</item>
</string-array>
</resources>
在 main_activity.xml 中加入 Spinner 元件的宣告。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Spinner android:id="@+id/spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
接著透過 ArrayAdapter.createFromResource
的靜態方法取得我們的字串表,這邊 simple_spinner_dropdown_item
是 Android 所提供的布局方式,還有其他的布局可以選擇,例如 simple_dropdown_item_1line
等等, 有興趣可以玩看看。
以下有個表可以使用各種的樣式。
https://developer.android.com/reference/android/R.layout.html#simple_spinner_dropdown_item
val adapter = ArrayAdapter.createFromResource(this, R.array.lunch, android.R.layout.simple_spinner_dropdown_item)
spinner.adapter = adapter
轉換成下拉式選單。
下拉後出現資料列表
加入資料 - 方法二
除了可以直接透過 strings.xml
的字串表轉換以外,也可以透過程式直接加入。
透過自己所建立的字串 lunch
,再利用 Android 內建的 ArrayAdapter 的方式,把程式內建立的字串塞進去,選擇好布局模式,就可以設定完成。
val lunch = arrayListOf("雞腿飯", "魯肉飯", "排骨飯", "水餃", "陽春麵")
val adapter = ArrayAdapter(this, android.R.layout.simple_spinner_dropdown_item, lunch)
spinner.adapter = adapter
這樣你就會看到這樣的畫面, 跟前面使用字串陣列表的呈現方式一樣。
下拉後出現資料列表
處理事件
如果要加入事件,會透過 Spinner 本身所提供,setOnItemSelectedListener
的方式來使用,注意:這邊不能使用 OnItemClickListener 否則會閃退
。
val lunch = arrayListOf("雞腿飯", "魯肉飯", "排骨飯", "水餃", "陽春麵")
val adapter = ArrayAdapter(this, android.R.layout.simple_spinner_dropdown_item, lunch)
spinner.adapter = adapter
spinner.onItemSelectedListener = object: AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>, view: View, pos: Int, id: Long) =
Toast.makeText(this@MainActivity, "你選的是" + lunch[pos], Toast.LENGTH_SHORT).show()
override fun onNothingSelected(parent: AdapterView<*>) {}
}
在 onItemSelected 事件中所代表的是當使用者按下 Spinner 的某個 item
該怎麼處理它們,這邊我們加入的一個提示訊息 Toast,它會在下方彈出一個小小的提示訊息, 並且在某段時間後就消失,如下圖所示。
下拉後出現資料列表。
如此一來就完成一個簡易的 Spinner 實作了。