LoginSignup
38

More than 3 years have passed since last update.

【Kotlin】ToolBarに戻るボタンをつける + Navigation

Last updated at Posted at 2019-05-31

はじめに

簡単そうなのに結構時間がかかったのでメモ。
「戻るボタンをつける」系の過去記事は、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ではバー下の影がなくなっているのがわかる。
スクリーンショット 2019-05-30 2.11.35.png
スクリーンショット 2019-05-30 2.10.30.png

戻るボタンをつけるまでの手順

MainActivityと、そこに乗せるFragment、さらに遷移先のFragmentをあらかじめ用意しておく。

Navigation Graphを作成する

resフォルダ配下で新たにnavigationフォルダを作成し、その中で遷移グラフを作成する。
(Android Studio3.4では、PreferencesからNavigation Editorにチェックを入れる工程は不要)
スクリーンショット 2019-05-30 1.43.49.png

navigation_graph.xml
<?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_graphNavHostFragmentに設定する。

activity_main.xml
<?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に下記のように記述することで、遷移先で戻るボタンが表示されるようになる。

MainActivity.kt
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

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
38