ユーザーにちょっとした項目を選択してもらいたいときに便利なのは Spinner です。プルダウンで選択項目が現れる簡単なアプリをKotlinで作ってみましょう。
2024.1.1
Spinner
レイアウトにスピナーを追加するには <Spinner /> の要素で行います。
1 2 3 4 |
<Spinner android:id="@+id/spinner" ... /> |
また、Spinnerの構成は ListView に似ています。
選択肢を設定
選択させたい項目を作ります。例えばArrayで作成すると
1 2 3 4 5 6 |
val spinnerItems = arrayOf( "Spinner", "Android", "Apple", "Windows" ) |
この項目の作成方法は色々あります。
resourceでリストを作ったり、Spinnerに要素をaddしたり。
個人的には要素を把握しやすいのでいつもArrayList、あるいは配列にします。
Spinnerのインスタンス生成、Adapterを設定
ArrayAdapterに設定します。
これを使うと、その選択肢をいい具合に並べて設定をしてくれます。
1 2 3 4 5 |
val adapter = ArrayAdapter( applicationContext, android.R.layout.simple_spinner_item, spinnerItems ) |
simple_spinner_item はプラットフォームによって提供され、デフォルトのレイアウトとして使用できます。レイアウトを自分で作成する必要はありません。
1 |
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) |
setDropDownViewResource(int) 、ユーザーが選択しようとするときにドロップダウンによりリストを表示するのに使うレイアウトを指定します。
simple_spinner_dropdown_item もプラットフォームで定義された標準的なレイアウトですので、このレイアウトも作る必要はありません。
選択肢が選択された時の処理
Spinner にリスナーを登録、選択された場合の挙動を記述します。
Spinner でアイテムが選択されると(on-item-selected)AdapterView.OnItemSelectedListener インターフェースでリスナー登録できるようにし、選択された時に対応する onItemSelected() コールバック メソッドを実装します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// リスナーを登録 spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener{ // アイテムが選択された時 override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { val spinnerParent = parent as Spinner val item = spinnerParent.selectedItem as String //textView.text = item } // アイテムが選択されなかった override fun onNothingSelected(parent: AdapterView<*>?) { // } } |
サンプルコード
ViewBindingでまとめてみます
MainActivity.kt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
//package com.example.kotlinspinner import android.os.Bundle import androidx.activity.enableEdgeToEdge import androidx.appcompat.app.AppCompatActivity import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat import android.widget.AdapterView import android.widget.ArrayAdapter import android.widget.Spinner import android.view.View import com.example.kotlinspinner.databinding.ActivityMainBinding class MainActivity : AppCompatActivity() { private lateinit var binding: ActivityMainBinding // 選択肢 private val spinnerItems = arrayOf("Spinner", "Android", "Apple", "Windows") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) ViewCompat.setOnApplyWindowInsetsListener(binding.root) { v, insets -> val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()) v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom) insets } // ArrayAdapter val adapter = ArrayAdapter(applicationContext, android.R.layout.simple_spinner_item, spinnerItems) adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) // spinner に adapter をセット // View Binding binding.spinner.adapter = adapter // リスナーを登録 binding.spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener{ // アイテムが選択された時 override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { val spinnerParent = parent as Spinner val item = spinnerParent.selectedItem as String // View Binding binding.textView.text = item } // アイテムが選択されなかった override fun onNothingSelected(parent: AdapterView<*>?) { // ... } } } } |
activity_main.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#4cfd" tools:context=".MainActivity"> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#00f" android:textSize="30sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.2" /> <Spinner android:id="@+id/spinner" android:background="#fff" android:layout_width="200dp" android:layout_height="wrap_content" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.3" /> </androidx.constraintlayout.widget.ConstraintLayout> |
build.gradle
1 2 3 4 5 6 7 8 |
... android { ... buildFeatures { viewBinding = true } } ... |
サンプル動画
Spinnerの文字サイズを変更したい場合は、レイアウトをカスタムで ArrayAdapter に設定するとできます。
関連ページ:
References:
Spinners
ArrayAdapter | Android Developers