しめ鯖日記

swift, iPhoneアプリ開発, ruby on rails等のTipsや入門記事書いてます

【Kotlin】AndroidのActionViewを試してみる

ActionViewとはアプリバー上に色々なViewを表示できる機能です。
ボタンを押したらアプリバーに検索用の文字入力を表示するといった事ができるようになります。
今回は下URLを参考に試しました。

アクション ビューとアクション プロバイダの使用  |  Android デベロッパー  |  Android Developers

まずは新規プロジェクトを作成します。

アプリを作成したらmenu_main.xmlを下のように変更します。

<menu 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"
    tools:context="com.example.myapplication.MainActivity">
    <item
        android:id="@+id/action_search"
        android:title="検索"
        app:showAsAction="ifRoom|collapseActionView"
        app:actionViewClass="android.widget.SearchView" />
</menu>

アプリを起動すると下のような表示になります。

検索ボタンを押すと下のように検索画面になります。
この検索アイコンを押すと文字入力も可能です。

xmlで設定したshowAsActionのifRoomとcollapseActionViewについても見ていきます。
ifRoomはスペースがあればメニューをアプリバーに表示するというものです。
ifRoomを外すと下のように右上のボタン内に収納されます。

ifRoomを指定しても入り切らない場合は下のように収納されます。

collapseActionViewはActionViewの折りたたみが可能になるオプションです。
これがないと下のように「←」ボタンが表示されなくなります。

この辺りのオプションは下URLを参考にしました。

メニュー リソース  |  Android デベロッパー  |  Android Developers

次は検索フォームで文字入力した時のイベントを取ってみます。

SearchViewの取得方法は下の通りです。
onCreateOptionsMenu内でmenuからアイテムを取得、そのアイテムからActionViewを取得しています。

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    menuInflater.inflate(R.menu.menu_main, menu)
    val searchView = menu.findItem(R.id.action_search).actionView as? SearchView
    searchView?.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
        override fun onQueryTextChange(newText: String?): Boolean {
            Log.d("TEST", "onQueryTextChange")
            return true
        }

        override fun onQueryTextSubmit(query: String?): Boolean {
            Log.d("TEST", "onQueryTextSubmit")
            return true
        }
    })
    return true
}

ActionViewでは下のような独自クラスを指定することも可能です。

class MyClass(context: Context): androidx.appcompat.widget.AppCompatTextView(context) {
    init {
        text = "テスト"
    }
}

xml側では下のように指定します。

<menu 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"
    tools:context="com.example.myapplication.MainActivity">
    <item
        android:id="@+id/action_search"
        android:title="検索"
        app:showAsAction="ifRoom|collapseActionView"
        app:actionViewClass="com.example.myapplication.MyClass" />
</menu>

実行するとアプリバーに先程作ったTextViewを表示できます。

actionLayoutという属性を使うとlayoutファイルを指定する事も可能です。
app:actionLayoutではなくandroid:actionLayoutにすると何も表示されないので注意が必要です。

<menu 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"
    tools:context="com.example.myapplication.MainActivity">
    <item
        android:id="@+id/action_search"
        android:title="検索"
        app:showAsAction="ifRoom|collapseActionView"
        app:actionLayout="@layout/test" />
</menu>

layout/testの中身は下の通りです。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#999">

    <TextView
        android:id="@+id/action_view_text"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="テスト"
        android:background="#999" />
</LinearLayout>

実行してボタンを押すと下のように表示されます。

ActionViewのレイアウトのTextViewは下のように取得できます。

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    menuInflater.inflate(R.menu.menu_main, menu)
    val actionView = menu.findItem(R.id.action_search).actionView
    val textView = actionView?.findViewById<TextView>(R.id.action_view_text)
    return true
}