LoginSignup
18
14

More than 5 years have passed since last update.

ToolbarをDataBindingで扱うTips

Posted at

Overview

DataBindingを使ってToolbarを扱う時のTipsをまとめます。
ListenerやCustom BindingAdaptersを使うので好みもあると思いますが、ViewModelやPresenterクラスをbindして実装する場合には便利なのでどんなことができるのかをざっと知っておきましょう。

メニューの制御

Toolbar上のメニューをinflateし、タップしたときのイベントをハンドリングします。
inflateMenuResIdというBindingAdapterを作って実現します。

ToolbarBindingAdapters.kt
@BindingAdapter("inflateMenuResId")
fun Toolbar.setInflateMenu(@MenuRes menuResId: Int?) {
    if (menu.isEmpty() && menuResId != null && menuResId != 0) {
        inflateMenu(menuResId)
    }
}
layout/{layout}.xml
<layout>
    <data>
        <import type="com.konifar.sample.R" />

                <variable
            name="viewModel"
            type="com.konifar.sample.SampleViewModel" />
    </data>
    ...

        <androidx.appcompat.widget.Toolbar
            ...
            app:inflateMenuResId="@{R.menu.sample_menu}"
            app:onMenuItemClick="@{viewModel::onMenuItemClick}" />
SampleViewModel.kt

fun onMenuItemClick(@Suppress("UNUSED_PARAMETER") menu: MenuItem): Boolean {
    // メニューがタップされた時の処理
    return true
}

ViewModelにmenuResIdのようなIntの値を持ってバインドすることで、動的にメニューを変更することもできます。

Navigationアイコンのタップ制御

Toolbar左上のアイコンを変更したり、タップしたときのイベントをハンドリングすることもできます。

layout/{layout}.xml
<layout>
    <data>
        <import type="androidx.core.content.ContextCompat" />

                <variable
            name="viewModel"
            type="com.konifar.sample.SampleViewModel" />
    </data>
    ...

        <androidx.appcompat.widget.Toolbar
            app:navigationIcon="@{ContextCompat.getDrawable(context, viewModel.navigationIconResId)}"
            app:navigationOnClickListener="@{viewModel::onNavigationClick}" />
SampleViewModel.kt
// 動的に変更する場合はObservableIntなどを使う
val navigationIconResId = R.drawable.back

fun onNavigationClick(@Suppress("UNUSED_PARAMETER") view: View) {
    // タップした時の実装
}

スクロール時のelevation変更

スクロールした時にToolbarに影をつけるための実装をDataBindingで共通化できます。
詳しくはこちら => https://qiita.com/konifar/items/4a5568b32f2ced664706#databinding-tips

ToolbarBindingAdapters.kt
@BindingAdapter("shadowAnimationScrollViewId")
fun Toolbar.setShadowAnimationScrollViewId(@IdRes scrollViewId: Int) {
    val scrollView = this.rootView.findViewById<View>(scrollViewId)
    if (scrollView is ScrollView) {
        scrollView.viewTreeObserver.addOnScrollChangedListener {
            isSelected = scrollView.canScrollVertically(-1)
        }
    }
}
layout/{layout}.xml
<androidx.appcompat.widget.Toolbar
    ...
    android:stateListAnimator="@animator/toolbar_elevation"
    app:shadowAnimationScrollViewId="@{R.id.scroll}" />

<ScrollView
    android:id="@+id/scroll"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    ...
</ScrollView>

DataBindingで共通化することで、xmlだけで簡単に画面を作れるようになるだけでなく、ViewModelでUnitTestが書きやすくなるというメリットもあります。プロジェクトやチームの様子を見ながら取り入れてみてください。

以上です。

18
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
14