AndroidのUIのひとつにSpinnerがあります。
いくつかの候補から対象を選ぶときに最適なドロップダウン(プルダウン)リストが主な使い道です。見た目は違いますが、iOSならUIPickerViewがそれに相当します。
package bar.foo.spinnersample | |
data class CustomSpinnerHolder(val name: String, val shortName: String) { | |
} |
Spinnerとリスト部分のレイアウトは基本的に変わりませんが、それぞれ名前(id)をつけます。
<?xml version="1.0" encoding="utf-8"?> | |
<TextView | |
xmlns:android="http://schemas.android.com/apk/res/android" | |
android:id="@+id/custom_spinner_short_name" | |
style="?attr/spinnerDropDownItemStyle" | |
android:singleLine="true" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:ellipsize="marquee" /> |
<?xml version="1.0" encoding="utf-8"?> | |
<TextView | |
xmlns:android="http://schemas.android.com/apk/res/android" | |
android:id="@+id/custom_spinner_name" | |
style="?attr/spinnerDropDownItemStyle" | |
android:singleLine="true" | |
android:layout_width="match_parent" | |
android:layout_height="?attr/dropdownListPreferredItemHeight" | |
android:ellipsize="marquee" /> |
package bar.foo.spinnersample | |
import android.content.Context | |
import android.view.LayoutInflater | |
import android.view.View | |
import android.view.ViewGroup | |
import android.widget.BaseAdapter | |
import android.widget.TextView | |
class CustomSpinnerAdapter(val context: Context, var dataSource: List<CustomSpinnerHolder>) : BaseAdapter() { | |
private val inflater: LayoutInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater | |
//region SpinnerAdapter | |
/** | |
* Gets a View that displays in the drop down popup the data at the specified position in the data set. | |
*/ | |
override fun getDropDownView(position: Int, convertView: View?, parent: ViewGroup?): View { | |
val view: View | |
val vh: ItemHolder | |
if (convertView == null) { | |
view = inflater.inflate(R.layout.spinner_artist_dropdown, parent, false) | |
vh = ItemHolder(view) | |
view?.tag = vh | |
} else { | |
view = convertView | |
vh = view.tag as ItemHolder | |
} | |
vh.label.text = dataSource.get(position).name | |
return view | |
} | |
//endregion | |
//region Adapter | |
/** | |
* How many items are in the data set represented by this Adapter. | |
*/ | |
override fun getCount(): Int { | |
return dataSource.size; | |
} | |
/** | |
* Get the data item associated with the specified position in the data set. | |
*/ | |
override fun getItem(position: Int): Any? { | |
return dataSource[position]; | |
} | |
/** | |
* Get the row id associated with the specified position in the list. | |
*/ | |
override fun getItemId(position: Int): Long { | |
return position.toLong(); | |
} | |
/** | |
* Get a View that displays the data at the specified position in the data set. | |
*/ | |
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View { | |
val view: View | |
val vh: SelectedItemHolder | |
if (convertView == null) { | |
view = inflater.inflate(R.layout.spinner_artist, parent, false) | |
vh = SelectedItemHolder(view) | |
view?.tag = vh | |
} else { | |
view = convertView | |
vh = view.tag as SelectedItemHolder | |
} | |
vh.label.text = dataSource.get(position).shortName | |
return view | |
} | |
//endregion | |
//region PRIVATE METHODS | |
private class SelectedItemHolder(row: View?) { | |
val label: TextView | |
init { | |
label = row?.findViewById(R.id.custom_spinner_short_name) as TextView | |
} | |
} | |
private class ItemHolder(row: View?) { | |
val label: TextView | |
init { | |
label = row?.findViewById(R.id.custom_spinner_name) as TextView | |
} | |
} | |
//endregion | |
} |
package bar.foo.spinnersample | |
import androidx.appcompat.app.AppCompatActivity | |
import android.os.Bundle | |
import android.view.View | |
import android.widget.AdapterView | |
import android.widget.Spinner | |
import android.widget.Toast | |
class MainActivity : AppCompatActivity() { | |
//region ITEMS ON SCREEN | |
private lateinit var spArtist: Spinner | |
//endregion | |
//region ITEMS ON SPINNER | |
val spinnerItems = listOf<CustomSpinnerHolder>( | |
CustomSpinnerHolder("ジミ・ヘンドリックス", "ジミヘン"), | |
CustomSpinnerHolder("エリック・クラプトン", "クラプトン"), | |
CustomSpinnerHolder("スティーヴィー・レイ・ヴォーン", "SRV"), | |
CustomSpinnerHolder("フランク・ザッパ", "ザッパ"), | |
CustomSpinnerHolder("ピート・タウンゼント", "ピート"), | |
CustomSpinnerHolder("スティーヴ・クロッパー", "クロッパー"), | |
) | |
//endregion | |
//region LIFECYCLE METHODS OF FRAGMENT | |
override fun onCreate(savedInstanceState: Bundle?) { | |
super.onCreate(savedInstanceState) | |
setContentView(R.layout.activity_main) | |
spArtist = findViewById<Spinner>(R.id.spnner_artist) | |
val adapter = CustomSpinnerAdapter(this, spinnerItems) | |
spArtist.adapter = adapter | |
spArtist.onItemSelectedListener = spinnerItemSelectedListener() | |
} | |
//endregion | |
//region ACTION EVENT | |
/** | |
* Spinnerが操作されたとき | |
*/ | |
private inner class spinnerItemSelectedListener : AdapterView.OnItemSelectedListener { | |
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { | |
when(parent?.id) { | |
R.id.spnner_artist -> { | |
Toast.makeText(this@MainActivity, spinnerItems[position].name, Toast.LENGTH_SHORT).show() | |
} | |
} | |
} | |
override fun onNothingSelected(parent: AdapterView<*>?) { | |
} | |
} | |
//region ACTION EVENT | |
} |