どうもこんばんわ。

本題

マテリアルデザインのライブラリでOutlineなDropDownMenu(Spinner)ないと思ってたけどあったので紹介。

環境

なまえ あたい
Android 10
言語 Kotlin

ライブラリ入れる

appフォルダの方にあるbuild.gradleを開いてdependencies{}の中に以下のコードを追加です。

1
2
// Material Design
implementation 'com.google.android.material:material:1.2.0-alpha06'

style.xmlを書き換える

Material Designのコンポーネント(UIの部品)を使うにはstyle.xmlを書き換えてTheme.MaterialComponents系をparentに指定する必要があるみたい。

style.xml

1
2
3
4
5
6
7
8
9
10
11
<resources>

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.MaterialComponents.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>

</resources>

レイアウト

説明によるとTextInputLayoutの中にAutoCompleteTextViewを入れることで実現されているらしい。

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
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:gravity="center"
android:orientation="vertical"
tools:context=".MainActivity">

<com.google.android.material.textfield.TextInputLayout
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.Dense.ExposedDropdownMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Outlineなドロップダウンメニュー">

<AutoCompleteTextView
android:id="@+id/auto_complete_textview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="false"
android:cursorVisible="false"
android:focusable="false"
android:inputType="none" />
</com.google.android.material.textfield.TextInputLayout>

</LinearLayout>

重要な点

AutoCompleteTextViewはテキストを補充するEditTextなため、ただ置くだけだとテキスト変更ができるどころかIMEが表示されます。
その対策に以下の値を設定しておく必要があります。(例ではすでに指定済みです。)

1
2
3
4
android:clickable="false"
android:cursorVisible="false"
android:focusable="false"
android:inputType="none"

なんか説明見る限りandroid:inputType="none"を指定すればユーザーの入力を無効にできるって書いてあるけど、そんなことなかったよ。

Kotlin

MainActivity.kt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

// Adapter作成
val menuList = arrayListOf("Java", "Kotlin", "JavaScript", "TypeScript")
val adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, menuList)
// Adapter登録
auto_complete_textview.setAdapter(adapter)
auto_complete_textview.setText(menuList[0], false)
}
}

これだけです。

さいごに

押したときにToastを出してみる

MainActivity.kt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

// Adapter作成
val menuList = arrayListOf("Java", "Kotlin", "JavaScript", "TypeScript")
val adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, menuList)
// Adapter登録
auto_complete_textview.setAdapter(adapter)
auto_complete_textview.setText(menuList[0], false)
// テキスト変更を検知
auto_complete_textview.addTextChangedListener {
Toast.makeText(this, it.toString(), Toast.LENGTH_SHORT).show()
}
}
}

参考にしました

https://stackoverflow.com/questions/41829665/android-studioedittext-editable-is-deprecated-how-to-use-inputtype/46073055

https://material.io/develop/android/components/menu/