phicdy devlog

Androidアプリ開発やその他技術系の記事をたまに書きます

AndroidとかiOSとかモバイル多め。その他技術的なことも書いていきます。

既存アプリのNavigation導入

Navigationを新規で入れるのは楽そうだなーと思いつつも現実的には既存アプリに入れることが多いと思う。自分の既存アプリに対して入れてみる。

developer.android.com

環境

起動ActivityをFragmentに移行する

一旦Toolbar等も含めて全部コピーしてFragmentに移してしまう。

メニューをFragmentに移す際は setHasOptionsMenu(true) を呼ばないとメニューが表示されない。 安直に移行すると差分が大きくなってGitの履歴が消えてしまう恐れがあるのでので一旦ファイル名&クラス名をFragmentに変えただけでコミットしておくと安心。

AndroidXになっていないFragmentをAndroidXに移行する

Navigationで使用するFragmentがAndroidXのものでないと遷移時にClassCastExcetpionでクラッシュする。 そんなことないだろと思うが私の場合は PrefrenceFragment がAndroidXになっていなかったので移行した。

Navigation導入

def navigation_version = '2.2.1'
implementation "androidx.navigation:navigation-fragment-ktx:$navigation_version"
implementation "androidx.navigation:navigation-ui-ktx:$navigation_version"

res/navigation/nav_graph.xml を作る。

  • app:startDestination で最初のFragmentを指定
  • fragmentにはlabelをつけておく
<?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/nav_graph"
    app:startDestination="@id/mainFragment">

    <fragment
        android:id="@+id/mainFragment"
        android:name="com.phicdy.navigationsample.MainFragment"
        android:label="main"
        tools:layout="@layout/fragment_main" />
</navigation>

Activityのレイアウト内の<fragment>NavHostFragment にする

    <fragment
        android:id="@+id/navHostFragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:navGraph="@navigation/nav_graph" />

遷移を指定

最初はUIから追加したが2個目からは直接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"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/nav_graph"
    app:startDestination="@id/mainFragment">

    <fragment
        android:id="@+id/mainFragment"
        android:name="com.phicdy.navigationsample.MainFragment"
        android:label="main"
        tools:layout="@layout/fragment_main">
        <action
            android:id="@+id/action_mainFragment_to_secondFragment"
            app:destination="@id/secondFragment" />
    </fragment>
    <fragment
        android:id="@+id/secondFragment"
        android:name="com.phicdy.navigationsample.SecondFragment"
        android:label="second"
        tools:layout="@layout/fragment_second" />
</navigation>

おわりに

とりあえず最初の導入まではすっといけた。他にもdeep linkやらsafe argやら他の機能もあるのでキャッチアップしていく。マルチモジュールで一覧→詳細→一覧みたいに循環して移動できる場合どうなるのかも気になる。