Exposed dropdown menus UIを個人アプリで取り入れる際、AutoCompleteTextViewを使った要素選択時の処理実装で少しだけ迷ったのでメモ程度に調べたことを記述します。
TL;DR
クリックによる要素選択時の処理にはonItemSelectedListenerではなくonItemClickListenerを使う
AutoCompleteTextView
AutoCompleteTextViewというViewがあります。
これは、複数の選択肢を表示するようなメニュー要素のUIを作りたい場合に活用できます。
Menus
Material Design Componentsの「Menus」の項目に詳細があります。
上記material.ioのサイトによると、メニューには二種類のタイプがあります。
- Dropdown menus
- Exposed dropdown menus
Dropdown menusはいろいろな形があるようですが、「選択肢のみを一覧で表示するような形のメニュー」という理解をしています。
一方、Exposed dropdown menusとは、「現在選択中の選択肢が一番上に表示され、その下に選択肢の一覧が表示される形のメニュー」という理解をしています。
個人アプリでは現在選択中の要素も表示したかったので、Exposed dropdown menusを作りたいと思い、AutoCompleteTextViewを使うことにしました。
詳細や適切な説明については上記公式サイトをご確認ください。
実装例
material.ioにも実装例のコードが載っているのでそちらもご覧ください。
公式サイトを参考に、個人アプリではこのようなXMLを記述しました。
AutoCompleteTextViewは、styleを適用したTextInputLayoutで囲うことでExposedDropdownMenuの見た目にすることができます。
xml version="1.0" encoding="utf-8"
<androidxconstraintlayoutwidgetConstraintLayout
xmlnsandroid="http://schemas.android.com/apk/res/android"
xmlnsapp="http://schemas.android.com/apk/res-auto"
xmlnstools="http://schemas.android.com/tools"
androidid="@+id/container"
androidlayout_width="match_parent"
androidlayout_height="wrap_content">
<comgoogleandroidmaterialtextfieldTextInputLayout
androidid="@+id/dropDownRoot"
style="@style/Widget.MaterialComponents.TextInputLayout.FilledBox.ExposedDropdownMenu"
androidlayout_width="0dp"
androidlayout_height="wrap_content"
applayout_constraintBottom_toBottomOf="parent"
applayout_constraintEnd_toEndOf="parent"
applayout_constraintStart_toStartOf="parent"
applayout_constraintTop_toTopOf="parent">
<AutoCompleteTextView
androidid="@+id/dropDown"
androidlayout_width="match_parent"
androidlayout_height="wrap_content"
androidinputType="none"
toolsignore="LabelFor" />
</comgoogleandroidmaterialtextfieldTextInputLayout>
</androidxconstraintlayoutwidgetConstraintLayout>
このような見た目になっています。
AutoCompleteTextViewの要素選択時の処理
個人アプリでは、要素を選択するたびにDBに選択肢を保存するような処理を行うよくあるような実装をするために、listenerをセットしました。
もともと、setOnItemSelectedListenerを呼び出してlistenerをセットしていましたが、なぜか要素を選択しても、リスナーが発火されませんでした。
原因を探すとそれっぽいものが
stackoverflow.com
setOnItemSelectedListenerではなくsetOnItemClickListenerを利用するべきだというようなものでした。
実際にsetOnItemClickListenerを利用することで問題は解決しました。
AutoCompleteTextViewのjavadocを見てもどちらを使うべきかぱっと見ではわからないので、気をつけてください、という話でした。
<p>Sets the listener that will be notified when the user clicks an item
in the drop down list.</p>
@param l
public void setOnItemClickListener(AdapterView.OnItemClickListener l) {
mItemClickListener = l;
}
<p>Sets the listener that will be notified when the user selects an item
in the drop down list.</p>
@param l
public void setOnItemSelectedListener(AdapterView.OnItemSelectedListener l) {
mItemSelectedListener = l;
}
以上となります。
誤った情報などもしありましたらコメントやツイッターにてご連絡いただけますと幸いです🙏
Reference