この2つの違いが曖昧なので、調べたことをメモしておきます。
ActionBar
どこで定義されている?
まずActionBarについて。ActionBarはアプリのテーマとして自動で定義されているもの。定義は、AndroidManifest
に
<application <!-- 中略 --> android:theme="@style/AppTheme >
として記載されていて、変更したい場合は、style.xml
のname="AppTheme"
の要素に以下のように定義を追記したり、属性値を変更すればよい。
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <!-- 中略 --> <item name="actionBarStyle"> </item> <style>
また、特別なことをしない限り自動でlayoutされ表示されます。
ActionBarの動作の記述
前述の通り、自動で生成されるViewですのでActivity内のコールバックメソッドで動作を記述するものがあります。以下は一例です。R.menu.~~~
のリソースファイルについての説明は省略します。
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) //タイトル名の変更 supportActionBar?.title = "ActionBar" //タイトルラベルの左側のナビゲーションアイテムの設置 supportActionBar?.setDisplayHomeAsUpEnabled(true) //ナビゲーションアイテムを変更 supportActionBar?.setHomeAsUpIndicator(android.R.drawable.sym_def_app_icon) //タイトルラベル右側のメニューアイテムの設置 override fun onCreateOptionsMenu(menu: Menu?): Boolean { getMenuInflater().inflate(R.menu.menu_item, menu); } //設置したアイテムのリスナーコールバック override fun onOptionsItemSelected(item: MenuItem?): Boolean { }
onOptionsItemSelected()
はすべてのアイテムからのコールバックとなるので、渡された引数MenuItem?
からどのアイテムが選択されたかを調べて処理する必要があります。
ActionBarを表示しない
ActionBarを表示しないようにするには
アプリ全体
アプリ全体で非表示にするにはstyle.xml
のAppTheme
に
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <item name="windowNoTitle">true</item> <!-- 中略 --> </style>
とします。
Activity個別
個別のActivityで制御する場合は、2種類の方法があります。
AndroidManifestで制御する
AndroidManifestで制御するには以下のようにandroid:theme
を記述してActionBarを無効にします。
<activity android:name=".MainActivity" android:theme="@style/AppTheme.NoActionBar">
Actiityコードで制御する
Activityの上のコード制御するにはhide()
メソッドを使用します。
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) supportActionBar?.hide() }
但し、supportActionBar?.hide()
をしたあとでsetSupportActionBar(toolbar)
とするとクラッシュするので、toolbarを使用する時には注意。
ToolBar
ToolBarは各layoutに記述するViewとなります。ほぼActionBarと同等な機能を有しますが、CoordinatorLayout
と組み合わせて動的にlayout制御することができたり、カスタマイズしやすいコンポーネント(らしい)です。
定義
定義はlayoutにて以下のように記述します。
<android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" android:theme="@style/ThemeOverlay.AppCompat.ActionBar" />
ToolBar定義時のActionBar
また記述後、以下のようにActionBarとToolBarが重複して表示されるケースがあります。
これは上記のActionBarの非表示化を行っていない為、ToolBarの上にActionBarが表示されてしまっている状態です。
また、画像のようにAppBarLayoutを使用した場合、ConstraintLayoutがToolBarの下に潜り込んでいる状態になる時があります。この場合、ConstraintLayoutにてapp:layout_behaviorを設定して問題を修正しました。
app:layout_behavior="@string/appbar_scrolling_view_behavior"
ToolBarの動作の記述
ToolBarはViewですので、他Viewと同様にメソッドにアクセスして利用します。
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_post_detail) //タイトルの変更 toolbar.setTitle(post.title) //タイトルラベルの左側のナビゲーションアイテムの設置 toolbar.setNavigationIcon(android.R.drawable.ic_delete) //ナビゲーションアイテムのリスナー toolbar.setNavigationOnClickListener { } //タイトルラベルの右側のメニューアイテムの追加 toolbar.inflateMenu(R.menu.menu_item) //メニューアイテムのリスナー toolbar.setOnMenuItemClickListener { menuItem -> }
ナビゲーションアイテムのリスナーは個別にありますが、メニューアイテムsetOnMenuItemClickListener()
のリスナーは各アイテム共通ですので、引数menuItem
からどのアイテムがClickされたかを判断して処理を記述します。
setSupportActionBar(toolbar)
setSupportActionBar()
はToolBarをActionBarのメソッドを利用して操作できるAdapterのようです。既存で実装していたActionBarからToolBarに変更する時のサポートメソッドのように見受けられます?
このメソッドを実行したあとは、toolbar自体が持つメンバメソッドが機能しなくなるので注意します。