Android(Kotlin)Navigation アプリバー対応

2020/8/29

はじめに

前回 、Navigation コンポーネントで画面遷移を実装しました。今回はアプリバーも対応してみます (後述する差分は前回の記事からの差分になります)。

実装内容

概要

対応内容は下記のの通りです。

  • アプリバー表示
  • アプリバー内に該当画面名を表示
  • アプリバー内に戻る(左矢印)ボタン

アプリバーは ActionBar ではなく、androidx.appcompat.widget.Toolbar を利用します。

差分

app/build.gradle

Cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6. Please specify proper '-jvm-target' option

とエラーメッセージが出たので対応します。

@@ -17,6 +17,10 @@ android {
         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
     }
 
+    kotlinOptions {
+        jvmTarget = '1.8'
+    }
+
     buildTypes {
         release {
             minifyEnabled false

app/src/main/java/com/example/myapplication/MainActivity.kt

Navigation コンポーネントと ToolBar との紐付けをします。 プログラム的にはこれだけでよしなにやってくれます。簡単ですね。

@@ -2,10 +2,19 @@ package com.example.myapplication
 
 import androidx.appcompat.app.AppCompatActivity
 import android.os.Bundle
+import androidx.appcompat.widget.Toolbar
+import androidx.navigation.findNavController
+import androidx.navigation.ui.AppBarConfiguration
+import androidx.navigation.ui.setupWithNavController
 
 class MainActivity : AppCompatActivity() {
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         setContentView(R.layout.activity_main)
+
+        val navController = findNavController(R.id.nav_host_fragment)
+        val appBarConfiguration = AppBarConfiguration(navController.graph)
+        findViewById<Toolbar>(R.id.toolbar)
+            .setupWithNavController(navController, appBarConfiguration)
     }
 }

app/src/main/res/layout/activity_main.xml

Toolbar 表示です。 fragment の名前がよろしくなかったのでついでに修正しました。

@@ -7,8 +7,16 @@
     android:orientation="vertical"
     tools:context=".MainActivity">
 
+    <androidx.appcompat.widget.Toolbar
+        android:id="@+id/toolbar"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:background="?attr/colorPrimary"
+        android:minHeight="?attr/actionBarSize"
+        android:theme="?attr/actionBarTheme" />
+
     <fragment
-        android:id="@+id/fragment"
+        android:id="@+id/nav_host_fragment"
         android:name="androidx.navigation.fragment.NavHostFragment"
         android:layout_width="match_parent"
         android:layout_height="match_parent"

app/src/main/res/navigation/nav_graph.xml

アプリバー内に該当デスティネーションのラベルが表示されるので、 文字列リソースを引っ張ってくるようにします。

@@ -8,8 +8,8 @@
     <fragment
         android:id="@+id/firstFragment"
         android:name="com.example.myapplication.FirstFragment"
-        android:label="fragment_first"
-        tools:layout="@layout/fragment_first" >
+        android:label="@string/destination_first"
+        tools:layout="@layout/fragment_first">
         <action
             android:id="@+id/action_firstFragment_to_secondFragment"
             app:destination="@id/secondFragment" />
@@ -17,8 +17,8 @@
     <fragment
         android:id="@+id/secondFragment"
         android:name="com.example.myapplication.SecondFragment"
-        android:label="fragment_second"
-        tools:layout="@layout/fragment_second" >
+        android:label="@string/destination_second"
+        tools:layout="@layout/fragment_second">
         <action
             android:id="@+id/action_secondFragment_to_firstFragment"
             app:destination="@id/firstFragment" />

app/src/main/res/values/strings.xml

上記、アプリバー内画面表示対応の文字列リソース差分です。

@@ -1,3 +1,5 @@
 <resources>
     <string name="app_name">My Application</string>
+    <string name="destination_first">画面1</string>
+    <string name="destination_second">画面2</string>
 </resources>

app/src/main/res/values/styles.xml

アクションバーと重複していたので対応します。

@@ -1,6 +1,6 @@
 <resources>
     <!-- Base application theme. -->
-    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
+    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
         <!-- Customize your theme here. -->
         <item name="colorPrimary">@color/colorPrimary</item>
         <item name="colorPrimaryDark">@color/colorPrimaryDark</item>