はじめに
簡単そうなのに結構時間がかかったのでメモ。
「戻るボタンをつける」系の過去記事は、ToolBarでなくActionBarを使っていたり、Navigationを使っていなかったりする記事が多いので注意が必要です(実装方法がだいぶ違います)。
環境
- macOS: 10.14.1
- Android Studio: 3.4
- kotlin: 1.3.21
- Support Library: AndroidX
Toolbarについておさらい
- Android 5.0 (Lollipop)で従来のActionBarの代わりに追加されたコンポーネント
- マテリアルデザインの導入に合わせて、ヘッダーまわりの考え方を整理する中で生まれた
- ActionBarに比べて柔軟性が高く、他のビューのスクロールに合わせてアニメーションしやすい
比べてみるとToolBarではバー下の影がなくなっているのがわかる。
戻るボタンをつけるまでの手順
MainActivityと、そこに乗せるFragment、さらに遷移先のFragmentをあらかじめ用意しておく。
Navigation Graphを作成する
res
フォルダ配下で新たにnavigation
フォルダを作成し、その中で遷移グラフを作成する。
(Android Studio3.4では、Preferences
からNavigation Editor
にチェックを入れる工程は不要)
<?xml version="1.0" encoding="utf-8"?>
<navigation
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/navigation_graph"
app:startDestination="@id/pagerFragment">
<fragment
android:id="@+id/pagerFragment"
android:name="com.example.my_app.ui.PagerFragment"
android:label="my_app">
<action
android:id="@+id/action_to_detail"
app:destination="@id/detailFragment"/>
</fragment>
<fragment
android:id="@+id/detailFragment"
android:name="com.example.my_app.ui.DetailFragment"
android:label="DetailFragment"/>
</navigation>
※詳細な手順は下記記事あたりを参考にしてください。
Android 10分で作る、Navigationによる画面遷移 - Qiita
activity_main.xmlの設定
activity_main.xml
にはToolbarを設置し、先程作成したnavigation_graph
をNavHostFragment
に設定する。
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"/>
<fragment
android:id="@+id/nav_host_fragment"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:name="androidx.navigation.fragment.NavHostFragment"
app:navGraph="@navigation/navigation_graph"
app:defaultNavHost="true"/>
</LinearLayout>
</layout>
app:defaultNavHost
をtrueにしておくとBackボタン(端末左下のボタン)で戻れるようになる。
ActionBarを無効にする
ActionBarがデフォルトでセットされているので、それを無効にしないとToolBarは表示されず、下記のようなエラーに苦しめられることになる。
This Activity already has an action bar supplied by the window decor. Do not request Window.FEATURE_ACTION_BAR and set windowActionBar to false in your theme to use a Toolbar instead.
styles.xml
のAppThemeのparentを、Theme.AppCompat.Light.NoActionBar
に設定することでActionBarを無効化することができる。また、ToolBarの色のカスタマイズもここで一緒に行える。
<resources>
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- ToolBarの背景色 -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<!-- ToolBarのタイトルテキスト色 -->
<item name="android:textColorPrimary">@color/white</item>
</style>
</resources>
戻るボタンを表示させる
MainActivityに下記のように記述することで、遷移先で戻るボタンが表示されるようになる。
class MainActivity : AppCompatActivity() {
private val binding by lazy {
DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setSupportActionBar(binding.toolbar)
val navController = findNavController(R.id.nav_host_fragment)
val appBarConfiguration = AppBarConfiguration(navController.graph)
setupActionBarWithNavController(navController, appBarConfiguration)
}
override fun onSupportNavigateUp()
= findNavController(R.id.nav_host_fragment).navigateUp()
}
setSupportActionBar
でToolBarをActionBarとしてセットする。
appBarConfiguration
に遷移グラフを渡すことで、戻るボタンの表示/非表示などをいい感じに管理してくれるようになる。
setupActionBarWithNavController()
を呼ぶことで戻るボタンが表示されるようになるのだが、これだけではボタンを押しても何も反応してくれない。
onSupportNavigateUp()
をオーバーライドすることで初めて、戻るボタンが機能するようになる。
参考
Android公式 - Update UI components with NavigationUI
Navigation Architecture Componentを試してみる - Qiita
MaterialDesignことはじめ ActionBar編 - Qiita
AndroidのToolBar(新しいActionBar)メモ - Qiita
ToolBar(ActionBar)を自前で作りたいときに遭遇するエラーへの対処 - Qiita
Android 10分で作る、Navigationによる画面遷移 - Qiita
【Android】Google IO 2018で新発表された navigation についての詳細レポート - DMM inside