4
5

More than 3 years have passed since last update.

Navigation Componentで新規登録画面の実装方法(graphのネストと戻るボタンの実装)

Posted at

はじめに

Navigation Component を使うと新規登録画面の画面遷移が簡単に実装できると耳にしました。
公式サイトにも実装方法が記載されていますが、なかなか難しかったので記事としてまとめます。

動作環境

この記事の動作環境は以下のとおりです。

Android Studio:4.1.1
Kotln:1.4.21
Open JDK:1.8
compileSdkVersion:30
targetSdkVersion:30
minSdkVersion:23
Navigation Component:2.3.2

目標

以下を目標とします。

  • Navigation Component UIで新規登録の画面遷移を実装できる

動作イメージ

こんな動きをする新規登録の画面遷移を Navigation Component で実装したい!!

機能概要

よくある話ですが、アプリをインストールして 新規登録 をタップして、ウィザード形式でユーザ登録などを行います。
登録が完了した画面や登録完了後に戻ってきたログイン画面で戻るボタンなどをタップすると正しい画面遷移ができています。
下図のようなイメージです。

01_実現したい機能.png

これってどのように実装しているのだろうと不思議に思うこともあります。
Navigation Componentに、公式サイトに実現の助けになるような機能が搭載されています。
この記事では実現方法を説明していきます。

Fragmentの動作

まず、実装方法の前にFragmentの画面やオブジェクトがどのように管理されているか理解して置く必要があります。
Navigation Componentでは、Fragmentの画面はActivityと同じ用にスタックで管理されています。
下図様なイメージです。

02fragmentのスタック.png

そのため、完了画面に遷移したあと、戻るボタンをタップするとデフォルトの動きでは確認画面に遷移していまいます。
これがFragmentの基本的な動作となります。
そのため、完了画面から戻るボタンや戻る機能を追加するときに、Login画面までスタックをクリアする必要があります。
上記の内容を理解した上で、実装方法を確認してください。

実装方法

前提知識

実装方法の前提知識としては、この記事を理解しておいてください。

アクション

画面遷移でスタックをクリアしたい画面にアクションを接続することにより実現可能です。
下図の様なイメージで、完了画面からログイン画面にアクションを接続します。

03_navigationファイル.png

graphのネスト

デスティネーションが増えていくと、navigationファイルの編集画面が操作しづらくなってしまいます。
なので、機能毎などでgraphをネストするとわかりやすくなります。

1機能のデスティネーションをすべて選択した状態で、「 group into nest graph 」ボタンをクリックします。
操作方法は下図を参照してください。

04_navigationのネスト方法.png

group into nest graph 」ボタンをクリックすると、ネストしたgraphは 角がまるい四角 になります。
ネストしたgraphの詳細を確認したい場合は、 角がまるい四角 をダブルクリックするだけで下図が表示されます。

05_ネストした中身の確認.png

ネストしたgraphからもとの画面に戻りたい時は、Component Treeで外側をクリックすると元の画面に戻ります。

06_ネストの外を表示.png

実際のコードを確認すると、navigationタグがネストしていることが確認できます。

07_コードで確認.png

ネストを利用することにして、機能ごとにnavigaitonをまとめられるので便利ですね。
navigationファイルを新規作成してincludeしても同じ事が行なえます。

スタックを指定したFragmentまでクリアする

先に説明した通り、ウィザード形式のように元の画面までスタックをクリアするには以下の手順を行います。

  1. アクションに設定を追加する

アクションタグの属性に以下の2つを設定します。

  • popUpTo属性
  • popUpToInclusive属性

最終的に下記のようなアクションになります。

<action
    android:id="@+id/action_completeToRegisterUserFragment_to_loginFragment"
    app:destination="@id/loginFragment"
    app:popUpTo="@id/loginFragment"
    app:popUpToInclusive="true" />

popUpTo属性

公式サイトに説明があります。

Navigation ライブラリに対し、navigate() 呼び出しの一環として、バックスタックからいくつかのデスティネーションをポップするように指示します。属性値として、スタック上に残す最も新しいデスティネーションの ID を指定します。

スタックにある、navigationは一番新しいデスティネーションを探し出してくれるみたいですね。
しかし、これだけではうまく動作しません。

popUpToInclusive属性

こちらも公式サイトに説明があります。

app:popUpToInclusive="true" を追加すると、app:popUpTo 内で指定したデスティネーションもバックスタックから削除するように指示できます。

これで古いLogin画面を削除してアクションので指定しているデスティネーションを新規にスタックに乗っけているわけですね。

なるほど、その他の説明もかいてありますが、興味のある方は公式サイトを参照してください。

戻るボタンの処理を変更する

Androidで用意されているソフトウェアやハードウェアの戻るボタンの挙動も修正しなければなりません。
公式サイトに詳しく書かれていますが、どうやら ** OnBackPressedDispatcher#addCallback** で戻るボタンの挙動を変えるみたいです。

実際のコードは以下の通りです。

// 戻るボタンを押下されても、ログイン画面に戻るようにこの画面のライフサイクル中の戻るボタンのコールバックを変更
requireActivity().onBackPressedDispatcher.addCallback(this) {
    val navController = findNavController()
    val action =
        CompleteToRegisterUserFragmentDirections.actionCompleteToRegisterUserFragmentToLoginFragment()
    navController.navigate(action)
}

addCallback() メソッドの引数に ライフサイクルオーナーを渡す方法渡さない方法 があります。

違いは以下のとおりです。

方法 挙動
ライフサイクルオーナーを渡す方法 そのライフサイクルの間、Callbackで指定した戻るボタンの挙動が有効になる
ライフサイクルオーナーを渡さない方法 アプリが終了するまで、Callbackで指定した戻るボタンの挙動が有効にになる

今回のケースでは、ライフサイクルオーナーを渡す方法が正しいとなります。

以上で実装は完了です。

まとめ

Androidアプリでウィザード形式を実装する方法がとても簡単になりました。
Navigation Componentを今まで避けて通ってきてきた私でしたが、今後は積極的に利用したくなりました。

4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5