Android Kotlin基礎講座 03.2: ナビゲーションパスを定義する
目次 [表示]
タスク:ナビゲーションドロワーを追加する
このタスクではAndroidTriviaアプリにナビゲーションドロワーを追加します。ナビゲーションドロワーとは画面の端からスライドアウトするパネルのことです。ドロワーは一般的にはヘッダーとメニューを含んでいます。
携帯サイズの端末では、利用しない際にはナビゲーションドロワーは隠れています。二つの方法でナビゲーションドロワーを表示させることができます:
- 画面のスタート端からエンド端に向かってスワイプする。AndroidTriviaアプリにおいては、左端から右端にスワイプすることで、ナビゲーションドロワーを表示することができます。
- ユーザーがアプリの最初の画面にいる状態で、アプリバーのドロワーアイコンをタップする。(ドロワーアイコンはナブドロワーボタン、ハンバーガーアイコンと呼ばれることもあります)
以下のスクリーンショットはナビゲーションドロワーを表示しています。
ナビゲーションドロワーはMaterial Components for Androidライブラリの一部です。簡単にMaterialライブラリと呼ぶこともあります。MaterialライブラリはGoogleのマテリアルデザインガイドラインのパターンを実装する際に利用します。
AndroidTriviaアプリでは、ナビゲーションドロワーには二つのメニューアイテムが含まれます。一つ目はaboutフラグメントにつながるアイテムで、二つ目はこれから実装するrulesフラグメントにつながるアイテムです。
ステップ1:Materialライブラリをプロジェクトに追加する
- アプリレベルのGradleビルドファイル(build.gradle(Module: app))にMaterialライブラリの依存関係を追加してください。
dependencies {
...
implementation "com.google.android.material:material:$supportlibVersion"
...
}
- プロジェクトをSyncしてください。
ステップ2:遷移フラグメントがIDを持っていることを確認する
ナビゲーションドロワーはそれぞれのフラグメントに移動することができる二つのメニューアイテムを持ちます。それら両方の遷移先ともナビゲーショングラフにおけるIDをもっている必要があります。
AboutFragmentは既にIDを持っていますが、RulesFragmentは持ってないので、これから追加します。
- fragment_rules.xmlを開いてください。Designタブをクリックして、デザインエディターにプレビューを表示してください。
- navigation.xmlファイルを開いてください。New Destinationボタンをクリックして、rules fragmentを選択してください。IDをrulesFragmentとしてください。
ステップ3:ドロワーメニューとドロワーレイアウトを作成する
ナビゲーションドロワーを作成するために、ナビゲーションメニューを作成します。またレイアウトファイルで、ビューを<DrawerLayout>中に置く必要があります。
- ドロワー用のメニューを作成します。プロジェクトパネルのresフォルダー上で右クリックしてNew > New Resource Fileを選択してください。名前をnavdrawer_menuとし、Resource typeをMenuにしてOKをクリックしてください。
- Designタブでnavdrawer_menu.xmlを開いてください。パレットからコンポーネントツリーにドラッグして二つのメニューアイテムを追加してください。
- 一つ目のメニューアイテムのidをrulesFragmentにしてください。(このIDはフラグメントのIDと同じである必要があります)titleは@string/rulesを選択し、iconには@drawable/rulesを選択してください。
- 二つ目のメニューアイテムのidをaboutFragmentにし、titleを@string/about、iconを@drawable/about_android_triviaにしてください。
Note: メニューアイテムのIDに遷移先のフラグメントの同じIDを用いることで、onClickリスナーの実装のためのコードを一切書く必要がなくなります。
- activity_main.xmlを開いてください。全てのドロワーを簡単に取得するために、DrawerLayoutの中に全てのビューを配置します。
<LinearLayout>全体を<DrawerLayout>で包みます。(言い換えれば、DrawerLayoutをルートビューとして追加します)
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.drawerlayout.widget.DrawerLayout
android:id="@+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
. . .
</LinearLayout>
</androidx.drawerlayout.widget.DrawerLayout>
</layout>
- 次に先ほど定義したばかりのnavdrawer_menuを利用しているNavigationView、すなわちドロワーを追加します。以下のコードをDrawerLayoutの中、</LinearLayout>要素の後に追加してください。
<com.google.android.material.navigation.NavigationView
android:id="@+id/navView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/nav_header"
app:menu="@menu/navdrawer_menu" />
ステップ4:ナビゲーションドロワーを表示する
ナビゲーションドロワー用のメニューアイテムとナビゲーションドロワーレイアウトを作成しました。ここからはユーザーがナビゲーションドロワーのアイテムを選択したときに適切なフラグメントに遷移できるようにするために、ナビゲーションドロワーをナビゲーションコントローラーに接続する必要があります。
- Mainactivity.ktを開いてください。onCreate()中にユーザーがナビゲーションドロワーを表示できるようにするためのコードを追加します。setupWithNavController()を呼び出すことで実現できます。以下のコードをonCreate()の最後に追加してください。
NavigationUI.setupWithNavController(binding.navView, navController)
- アプリを起動してください。左端からスワイプしてナビゲーションドロワーを表示してください。それぞれのメニューアイテムが適切な場所につながっているかを確認してください。
ナビゲーションドロワーが正常に機能するためにはもう一つ修正する部分があります。普通のアプリはユーザーはドロワーボタンをタップすることでもナビゲーションドロワーを表示することができます。現段階ではドロワーボタンは表示できていません。
ステップ5:ドロワーボタンからナビゲーションドロワーを表示する
最後のステップではユーザーがアプリバーのドロワーボタンからナビゲーションドロワーを表示できるようにします。
- MainActivity.kt中に、ドロワーレイアウトを表すlateinit drawerLayoutメンバ変数を追加してください。
private lateinit var drawerLayout: DrawerLayout
Note: Kotlinはnull安全な言語です。null安全を確保する方法の一つとしてlateinitを使う方法があります。これを使うことで変数の初期化をnull参照を返す危険性なしに遅らせることができます。
今回の場合は、drawerLayoutはnullableにする必要を避けるためにlateinitで宣言しました。この変数はonCreate()で初期化されます。
- onCreate()メソット中のbidining変数の初期化のあとでdrawerLayoutを初期化してください。
val binding = DataBindingUtil.setContentView<ActivityMainBinding>(this,
R.layout.activity_main)
drawerLayout = binding.drawerLayout
- setupActionBarWithNavConrtoller()メソッドの三つ目の引数にdrawerLayoutを追加してください。
NavigationUI.setupActionBarWithNavController(this, navController, drawerLayout)
- onsupportNavigateUp()変数を編集して、navController.navigateUpの代わりにNavigationUI.navigateUpを返すようにしてください。navigateUp()にナビゲーションコントローラーとドロワーレイアウトを渡します。メソッドは以下のようになります。
override fun onSupportNavigateUp(): Boolean {
val navController = this.findNavController(R.id.myNavHostFragment)
return NavigationUI.navigateUp(navController, drawerLayout)
}
- インポートが必要な場合は、全てインポートしてください。以下は必要なインポートの例です。
import androidx.drawerlayout.widget.DrawerLayout
- アプリを起動してください。スワイプでナビゲーションドロワーを表示し、それぞれのメニューアイテムが適切な場所につながっているかを確認してください。
- ホームスクリーンにいき、ドロワーボタンをおしてナビゲーションドロワーが表示されるか確認してください。
おめでとうございます!
アプリに異なるナビゲーションオプションを追加できました。
これでユーザーはゲームを一通りプレイすることができるようになりました。いつでもアップボタンを使ってホーム画面に戻ることもできます。オプションメニューからも、ナビゲーションドロワーからもAbout画面に飛ぶこともできます。戻るボタンはアプリの趣旨にそって機能するようにもなっています。
あなたが作成したアプリにはユーザーが直感的に使える論歴なナビゲーションパスが含まれています。
お疲れさまでした!
完成済みプロジェクト
完成済みプロジェクトは以下からダウンロードできます。