Android

NavigationViewのアイテムにトグルスイッチを付ける

actionLayout属性を使用する方法とsetActionViewする方法の2種類があるみたいです。個人的にはsetActionViewを使う方法が良さそうと思いました。

サンプルソースはGitHubに置いてあります。

setActionView

setActionViewを使用する場合、menu.xmlにはidだけ設定されていれば良いです。

res/menu/drawer_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:title="Item1" android:id="@+id/menu_item1" />
    <item android:title="Item2" android:id="@+id/menu_item2" />
    <item android:title="Item3" android:id="@+id/menu_item3" app:actionLayout="@layout/drawer_menu_item" />
</menu>

上のメニューのうち、Item2にトグルスイッチを配置する場合のソースの例です。

MainActivity.kt
val navigationView: NavigationView = findViewById(R.id.navigation_view)

// ...略...

// トグルスイッチの生成
val switch1 = Switch(this)
// トグルスイッチにイベントを設定
switch1.setOnCheckedChangeListener({button, isChecked ->
    val text = if (isChecked) "checked" else "unchecked"
    Toast.makeText(this, text, Toast.LENGTH_SHORT).show()
})
// トグルスイッチを配置するメニューを取得
val menuItem2 = navigationView.menu.findItem(R.id.menu_item2)
// 取得したメニューにトグルスイッチを設定
menuItem2.actionView = switch1

こんな感じに動作します。

switchtoggle.gif

actionLayout属性

actionLayout属性を使用する場合、まずmenu.xmlにactionLayout属性に使用するレイアウトを指定します。(以下のdrawer_menu.xmlで言えばItem3のように指定する。)

res/menu/drawer_menu.xml (再掲)
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:title="Item1" android:id="@+id/menu_item1" />
    <item android:title="Item2" android:id="@+id/menu_item2" />
    <item android:title="Item3" android:id="@+id/menu_item3" app:actionLayout="@layout/drawer_menu_item" />
</menu>

actionLayoutに指定したレイアウトのレイアウトファイルも作成します。setActionViewとは違うものを表示したいのでトグルボタンを表示するようにしました。

res/layout/drawer_menu_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ToggleButton
        android:id="@+id/toggle_button"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:text="ToggleButton" />
</LinearLayout>

ここまででトグルボタンは表示はされますが、押してもオンオフが切り替わるだけなので適当なイベントを設定します。

MainActivity.kt
val navigationView: NavigationView = findViewById(R.id.navigation_view)

// ...略...

// actionLayoutに設定したレイアウトから生成されたビューを取得
val customView: View = navigationView.menu.findItem(R.id.menu_item3).actionView
// ビューからトグルボタンを取得
val toggleButton: ToggleButton = customView.findViewById(R.id.toggle_button)
// トグルボタンにイベントを設定
toggleButton.setOnCheckedChangeListener { button, isChecked ->
    val text = if (isChecked) "checked" else "unchecked"
    Toast.makeText(this, text, Toast.LENGTH_SHORT).show()
}

こんな感じに動作します。

buttontoggle.gif

参考ページ