今更AndroidのToolbarについて理解できたような気がするのでメモ。
気のせいかもしれません。
Toolbar
Toolbar は Action Bar を一般化させたもので、同様の機能を備えつつ、より高い柔軟性を提供します。通常の Action Bar と異なる点は、Toolbar は階層内のビューの 1 つであるということです。そのため、Toolbar のインスタンスは好きなところに配置することができ、他のビューと共存します。さらに、動きを与えたり、スクロール イベントに反応させたりもできます。Activity.setActionBar() をコールすることで、Toolbar を Activity の Action Bar として機能させることもできます。
これがいまいち意味分からなかったので、原文読んでみました。
Toolbar
The toolbar is a generalization of the action bar pattern, providing similar functionality, but much more flexibility. Unlike the standard action bar, toolbar is a view in your hierarchy just like any other, so you can place instances wherever you like, interleave them with the rest of your views, animate, react to scroll events and so on. You can make the Toolbar act as your Activity’s Action Bar by calling Activity.setActionBar().
Implementing Material Design in Your Android app | Android Developers Blog
generalization of the action bar pattern
を「Action Bar を一般化」は全然意味違ってないです?「ActionBarパターンを普遍化させた」とかそんな感じのニュアンスに読めます。
toolbar is a view in your hierarchy just like any other
の部分、「他のビューと同じ階層にある」という点についてちょっと曖昧な書き方です。タイトルバー階層と、アプリが管理しているビュー階層が今までは別だったという前提が重要だと思いますので。
interleave them with the rest of your views
を「他のビューと共存」は意訳なのか自分の訳が悪いのか微妙ですけど、「他のビューの余白に挿入」ってだけに読めます。
ActionBarはビュー階層に解放されました
この記事がとても参考になりました。
~2.XからAndroidにはActivity
単位でラベルを表示できるタイトルバーの機能がありました。標準の見た目が残念すぎて、requestWindowFeature()
でカスタマイズができるにも関わらず、大抵非表示にされていました。
3.Xでタイトルバーは多機能なActionBarに置き換えられました。しかし「2.Xでタイトルバー非表示にしつつ、3.X~ではActionBarを表示」と分岐を入れるのは好まれず、またActionBarをバックポートできるのはActionBarSherlock
という非公式ライブラリしかなかったので、依然非表示にされたまま、ActionBarパターンの認知度はいまいちでした。
その状況が変わったのが2013年7月のAndroid Support Library
のrevision18
によるActionBarのバックポートです。時期的には4.3(Jelly Beanの最後のマイナーアップデート)になって、ようやく公式でActionBarがバックポートされ、「iOSとは違うAndroidのパターンを見直そう」という機運が高まります。
そして5.0になるわけですが、ここにきてActionBarの定義が大きく変わったように思います。ロゴ画像ではなくカラーを利用したブランディング、ユーザーの管理するビュー階層への移動、ActionBar組み込みのナビゲーション機能(setNavigationMode()
)の廃止。
もはやActionBarはユーザービュー階層にあるのですから、その実装はユーザー次第であると考えると、NavigationModeが廃止されたのも理解できます。
しかしタイトルバーを非表示にしてToolbar
を使うというのは、直感に反していて非常に微妙…。
2つあるToolbar
Toolbar
は2つあります。android.widget.Toolbar
とandroid.v7.widget.Toolbar
です。
Toolbar は AppCompat で完全にサポートされ、フレームワーク ウィジェットと同等の機能と API をもちます。
AppCompat v21 — Lollipop 搭載前のデバイスにマテリアル デザインを! - Google Developer Japan Blog
これ、前提としてandroid.widget.Toolbar
があって、その同等の機能がandroid.v7.widget.Toolbar
で提供されている、という意味なのですね…。実際使ってみるまでは、v7ライブラリ専用の機能だとばかり。
両者は実機能としては違いがないのですが、本家がandroid:Theme.Material
テーマを前提としているのに対して、v7版はTheme.AppCompat
テーマを前提としており、属性参照している値が異なります。
例によって、android:toolbarStyle
とtoolbarStyle
に分裂してるんでしょう。
Toolbarを使うときの注意
setSupportActionbar()
を呼んで、ActionBarとして使うときは、以下のようにレイアウト指定します。
<android.support.v7.widget.Toolbar android:id="@+id/my_awesome_toolbar" android:layout_height="wrap_content" android:layout_width="match_parent" android:minHeight="?attr/actionBarSize" android:background="?attr/colorPrimary" />
そうではなく、普通にViewGroup
として使うときには指定が変わります。
<android.support.v7.widget.Toolbar android:layoutheight="wrapcontent" android:layoutwidth="matchparent" android:minHeight="?attr/actionBarSize" app:theme="@style/ThemeOverlay.AppCompat.ActionBar" />
画面に複数のToolbar
を表示する場合に、それぞれに異なるスタイルを指定するためなのだと思いますが、トラップ感満載です。
ところで単純なViewGroup
としてみた場合、layout_gravity
がレイアウトエディタ上でサジェストされなくて使い勝手が悪いんですけど、バグなんでしょうねー…。