はじめに
KotlinでNavigationDrawerを実装する方法を忘れないために、メモがてら書いています。
コードを簡潔にするため、バインディングは使用していません。
環境
- Android Studio 4.1.1
- kotlin 1.4.10
事前準備
1. 画面の作成
各画面はフラグメントで実装するため、MainActivity以外に今回は
- HomeFragment
- ProfileFragment
- SettingsFragment
を用意する。
2. Navigation Graphの作成
画面遷移を管理するNavigationファイルを作成する。
res -> New -> Android Resource File
最初に作成した3つのフラグメントを追記する。
GUIからでもフラグメントを追加可能。
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/navigation"
app:startDestination="@id/homeFragment">
<fragment
android:id="@+id/homeFragment"
android:name="com.example.drawerexample.HomeFragment"
android:label="fragment_home"
tools:layout="@layout/fragment_home" />
<fragment
android:id="@+id/profileFragment"
android:name="com.example.drawerexample.ProfileFragment"
android:label="fragment_profile"
tools:layout="@layout/fragment_profile" />
<fragment
android:id="@+id/settingsFragment"
android:name="com.example.drawerexample.SettingsFragment"
android:label="fragment_settings"
tools:layout="@layout/fragment_settings" />
</navigation>
実装手順
1. 依存関係の追加
implementation 'com.google.android.material:material:1.2.1'
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.0'
implementation 'androidx.navigation:navigation-ui-ktx:2.3.0'
2. メニューのレイアウトファイル作成
res -> New -> Android Resource File
メニューに表示するアイテムを定義。
android:idはnavigation.xml
で定義している各フラグメントのidと同じ必要があるので注意。
アイテムにアイコンを表示する場合は、android:icon
を定義する。
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/profileFragment"
android:title="プロフィール" />
<item
android:id="@+id/settingsFragment"
android:title="設定" />
</menu>
3. DrawerLayoutを定義する
まず、ナビゲーションドロワーを追加するため、DrawerLayout
をルートビューとして宣言する。
既存のfragmentをNavHostFragment
に変更する。
次に、</LinearLayout>
の下にナビゲーションドロワーのビューを表示する用のNavigationView
を追加する。
<androidx.drawerlayout.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<fragment
android:id="@+id/navHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="androidx.navigation.fragment.NavHostFragment"
app:defaultNavHost="true"
app:navGraph="@navigation/navigation" />
</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:menu="@menu/navdrawer_menu" />
</androidx.drawerlayout.widget.DrawerLayout>
android:layout_gravity:どの方向からスワイプすることでメニューが表示されるかを設定する
app:menu:ドロワーメニューのレイアウトファイル(XML)を設定する
この時点で左から右にスワイプするとメニューが表示されるが、各アイテムをタップしても対象の画面に遷移されないため、MainActivity.kt
のonCreate()
に以下のコードを追加。
val navView: NavigationView = findViewById(R.id.navView)
val navController = this.findNavController(R.id.navHostFragment)
NavigationUI.setupWithNavController(navView, navController)
4. ドロワーボタンを追加する
このままではスワイプでしか表示することができないので、ドロワーを表示するためのボタンを設定する。
1. DrawerLayout変数を定義
private lateinit var drawerLayout: DrawerLayout
2. DrawerLayout変数を初期化
onCreate()
メソッド内で、drawerLayoutを初期化する。
drawerLayout = findViewById(R.id.drawerLayout)
3. DrawerLayoutをsetupActionBarWithNavController()に追加
NavigationUI.setupActionBarWithNavController(this, navController, drawerLayout)
4. onSupportNavigateUp()を追加
onCreate()
メソッドの下に追加する。
override fun onSupportNavigateUp(): Boolean {
val navController = this.findNavController(R.id.navHostFragment)
return NavigationUI.navigateUp(navController, drawerLayout)
}