Help us understand the problem. What is going on with this article?

BottomAppBar + FABのレイアウトでSnackbarがFABの上部に表示されない

概要

Android開発にて、Material ComponentsのBottomAppBarとFloatingActionButton(以下FAB)を使ってレイアウトを組んだ際に、Snackbarの表示位置がガイドライン通りになりませんでした。
使用したMaterial Componentsのバージョンは com.google.android.material:material:1.0.0-rc01です。

問題点

ガイドラインによると、表示位置はBottomAppBar + FABの上部が正しいとのこと。
image.png

しかし、上記バージョンでSnackbarを表示するとBottomAppBarの上に重なり、FABを押し上げる形で表示されてしまいます。

<androidx.coordinatorlayout.widget.CoordinatorLayout>

    <!-- some contents -->

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/floatingActionButton"
        app:layout_anchor="@id/bottomAppBar" />

        <com.google.android.material.bottomappbar.BottomAppBar
            android:id="@+id/bottomAppBar"
            android:layout_gravity="bottom"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Snackbar
    .make(
        view,
        R.string.message,
        Snackbar.LENGTH_LONG
    )
    .setAction(R.string.action) { doAction() }

image2.png

解決策

com.google.android.material:material:1.1.0-alpha01から、SnackbarにsetAnchorView(@IdRes int anchorViewId)というメソッドが追加されました。
このメソッドは、どのViewの上部にSnackbarを表示するか指定することができるメソッドです。
したがって、このメソッドを使いFABのIDを指定することでFABの上にSnackbarを表示することができるようになります。

Snackbar
    .make(
        view,
        R.string.message,
        Snackbar.LENGTH_LONG
    )
    .setAction(R.string.action) { doAction() }
    .setAnchorView(R.id.floatingActionButton) // FABの上部に表示するよう指定

image3.png

注意点

com.google.android.material:material:1.1.0-alpha01のBottomAppBarを使用すると、Android Pにてアプリがクラッシュする不具合が確認されています。

    java.lang.IllegalArgumentException: Invalid Region.Op - only INTERSECT and DIFFERENCE are allowed
        at android.graphics.Canvas.checkValidClipOp(Canvas.java:779)
        at android.graphics.Canvas.clipRect(Canvas.java:826)
        at com.google.android.material.shape.MaterialShapeDrawable.prepareCanvasForShadow(MaterialShapeDrawable.java:850)
        at com.google.android.material.shape.MaterialShapeDrawable.draw(MaterialShapeDrawable.java:746)
        at android.view.View.getDrawableRenderNode(View.java:20463)
        at android.view.View.drawBackground(View.java:20399)
        at android.view.View.draw(View.java:20198)

Issueにも挙がっているため、どこかのタイミングで修正されるのではないかと考えております。

2018/12/18追記

こちらのIssueですが1.1.0-alpha02で修正されました。
(リリースノート:https://github.com/material-components/material-components-android/releases/tag/1.1.0-alpha02)
AndroidPのエミュレータ、実機ともに動作を確認してクラッシュしないことを確認いたしました。

まとめ

  • BottomAppBar + FABのレイアウト構成にてSnackbarの表示位置がガイドラインと一致しない問題が発生。
  • Material Componentsのバージョンを1.0.0-rc01から1.1.0-alpha01にアップデート。
  • setAnchorView(@IdRes int anchorViewId)を用いてどのViewの上部に表示するか指定。
  • 1.1.0-alpha01のBottomAppBarを用いるとAndroid Pにてクラッシュが発生することに注意。(alpha02にて修正済み)

以上、ご精読ありがとうございました。

Material Designに関連する記事

角丸や切り欠きを表現するShapeの解説と、実際にアプリに適用した実例を紹介しています。
https://qiita.com/umechanhika/items/7497e34b18af279b3737

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away