ヘッダーのタイトルを変更する(2)
ツールバーとナビゲーションアーキテクチャコンポーネントを接続する
それでは、Kotlin側でツールバーとナビゲーションアーキテクチャコンポーネントをつなぎ込んでいきましょう。 MainActivityを編集します(リスト2)。
package com.example.navigation
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.appcompat.widget.Toolbar
import androidx.navigation.Navigation
import androidx.navigation.ui.NavigationUI
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// (1)
val navController =
Navigation.findNavController(this, R.id.fragment)
// (2)
val toolbar = findViewById<Toolbar>(R.id.toolbar)
// (3)
NavigationUI.setupWithNavController(toolbar, navController)
}
}
まずは、フラグメント内で NavControllerを扱ったときと同じように、(1)の形で NavControllerを呼び出します。アクティビティから呼び出す場合は、第一引数にアクティビティ自身、第二引数には NavHostFragmentが配置されたフラグメントのIDを指定します。その後、(2)でツールバーを呼び出したら、(3)で NavigationUIクラスの setupWithNavControllerメソッドを使ってつなぎ込みます。
ここまで設定すれば動くはずなので、一度実行してみましょう(図9)。
アクティビティ側のヘッダーが残ってしまいました。次はこれを見えないようにする作業が必要です。
アクティビティ側のヘッダーを消す
アクティビティ側のヘッダー(ActionBar)を削除するには、テーマの設定を変更する必要があります。 res/values/styles.xmlに記述されている親テーマ(parent)を、リスト3のように変更します。
<!-- Before --> <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <!-- After --> <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
DarkActionBarのテーマを NoActionBarのテーマに変更しました。これでアクティビティ側のヘッダーは消えたはずです。動かしてみましょう(図10)。
ちゃんと消えました。しかし、今度はテキストが黒くなってしまいました。テキストの色を戻しましょう。 res/layout/activity_main.xmlを開いて、ツールバーのテーマを変更します(図11)。
テーマの項目を @style/ThemeOverlay.AppCompat.Dark.ActionBarにして、再度アプリを実行してみると、今度はちゃんと文字も白くなります(図12)。
バッチリですね。
タイトルを変更する
他にヘッダー周りで気になるのは、タイトルの文字列がレイアウト名になっているところですね。前回も解説したとおり、タイトルを設定する場合には、ディスティネーションの Label要素を編集します。
今回は「ひとつめの画面」「ふたつめの画面」と名付けてみました。その結果、図14のようになりました。
うまくいきました。これで、最初よりもかなり画面遷移っぽくなりました。
連携できる他のUIコンポーネント
同様に、 NavigationUIクラスを利用することで、 CollapsingToolbarLayoutや BottomNavigationViewと連携することもできます。
興味がある方は、上記の公式ガイドラインを参考に、チャレンジしてみてください。
アニメーションを設定する
ヘッダーの動きがそれらしくなったので、次はアニメーションをつけてみましょう。公式のアニメーションリソースがまだ充実していないので、自分で用意します(図15)。
それぞれの中身は、リスト4のようになります。
<!-- res/anim/slide_in_left.xml -->
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="-100%" android:toXDelta="0%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="700"/>
</set>
<!-- res/anim/slide_in_right.xml -->
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="100%" android:toXDelta="0%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="700"/>
</set>
<!-- res/anim/slide_out_left.xml -->
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="0%" android:toXDelta="-100%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="700"/>
</set>
<!-- res/anim/slide_out_right.xml -->
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="0%" android:toXDelta="100%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="700"/>
</set>
次は、 res/navigation/nav_graph.xmlをナビゲーションエディタで編集して、アクションにアニメーションを登録します(図16)。
次のとおりの組み合わせで選択します。
-
Enter:
slide_in_right -
Exit:
slide_out_left -
Pop Enter:
slide_in_left -
Pop Exit:
slide_out_right
これだけで動けばよいのですが、もうひと手間必要です。 FirstScreenFragmentで画面遷移を実行していた navigate()メソッドの使い方を変更します(リスト5)。
// Before
view.findViewById<Button>(R.id.btn_goto_second)
.setOnClickListener { v ->
Navigation.findNavController(v)
.navigate(R.id.secondScreenFragment)
}
// After
view.findViewById<Button>(R.id.btn_goto_second)
.setOnClickListener { v ->
Navigation.findNavController(v)
.navigate(R.id.action_firstScreenFragment_to_secondScreenFragment)
}
これまでは navigate()メソッドに遷移先のディスティネーションのIDを設定指定していましたが、今回はアクションのIDを設定しています。ナビゲーションエディタでアクションの属性を見た場合の、図17の部分です。
引数を変更した navigate()メソッドを実行すると、図18のように、アニメーションしながら画面遷移を行う様子が見られます。
これだけを見ると、アクティビティを使う方式に比べて煩雑になっただけのようにも見えますが、アクション単位で画面遷移のアニメーションを切り替えるのが容易になったと捉えることもできます。下から出てくる画面や、ひっくり返る画面など、柔軟な画面遷移が今後増えていくと面白いですね。
