SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

一歩進んだAndroidアプリ開発ができる「Android Jetpack」入門

型安全なナビゲーションとKotlin DSLによるナビゲーション

一歩進んだAndroidアプリ開発ができる「Android Jetpack」入門 第16回

画面遷移時の型安全なデータ渡し

 Safe Argsを利用すると、画面遷移時に遷移先フラグメントに対してデータを渡す方法も、型安全になります。次にその方法を紹介していきます。

ナビゲーショングラフへの引数登録

 例えば、MemoDetailFragmentは、MemoListFragmentから遷移時に、タップされたリストデータの主キーidの値を受け取り、画面を表示するとします。通常のフラグメント間の遷移や、前回のリスト6では、Bundleオブジェクトであるargumentsを利用します。

 一方、画面遷移時に型安全でのデータの受け渡しを行う場合、まず、ナビゲーショングラフの遷移先デスティネーションに受け取るデータを登録する必要があります。ナビゲーショングラフにおいてmemoDetailFragmentを選択すると、Attributesツールバーは、図1の表示となっています。

図1:ナビゲーショングラフでのmemoDetailFragmentのAttributes
図1:ナビゲーショングラフでのmemoDetailFragmentのAttributes

 このAttributesのうちのArgumentsセクションの[+]をクリックすると、図2のAdd Argumentダイアログが表示されます。このダイアログが、まさにデスティネーションが受け取るデータを登録するためのものです。

図2:Add Argumentダイアログ
図2:Add Argumentダイアログ

 先述のように、MemoDetailFragmentは主キーidの値を受け取る必要があるので、図2のように、name(データ名)をmemoId、type(データ型)をLongとし、さらに、データをうまく受け取れなかった場合のための初期値(Default Value)として0Lを入力し、[Add]をクリックします。

 すると、Attributesツールバーは図3のように表示され、無事Argument(=引数)が登録されたのがわかります。

図3:引数として登録されたmemoId
図3:引数として登録されたmemoId

 ここで、XML記述を見ておきましょう。これはリスト5のようになっています。

[リスト5]res/navigation/nav_graph.xml
<?xml version="1.0" encoding="utf-8"?>
<navigation
  :
  app:startDestination="@id/memoListFragment">
    :
  <fragment
    android:id="@+id/memoDetailFragment"
    :
    tools:layout="@layout/fragment_memo_detail" >
    <argument
      android:name="memoId"
      app:argType="long"
      android:defaultValue="0L" />
  </fragment>
</navigation>

 idがmemoDetailFragmentのfragmentタグ内にargumentタグが自動的に定義されています。そして、属性として定義されている値は、まさに、図2で入力した値そのものです。

遷移先にデータを渡すコード

 このように遷移先画面に引数を定義すると、Javaコードの場合は、Action〇〇のインスタンスに、データを格納するためのデータ名のセッターが自動生成されています。そのため、リスト6の(1)と(2)の間に、(3)のコードを記述するだけでデータの格納が可能となります。ActionMemoListFragmentToMemoDetailFragmentの場合は、memoIdのセッター、すなわち、setMemoId()が自動生成されているので(1)で取得したactionに対して、(3)のようにsetMemoId()を実行してデータを格納します。

[リスト6]MemoListFragment.java
MemoListFragmentDirections.ActionMemoListFragmentToMemoDetailFragment action = MemoListFragmentDirections.actionMemoListFragmentToMemoDetailFragment();  // (1)
action.setMemoId(memoId);  // (3)
navController.navigate(action);  // (2)

 Kotlinの場合は、このセッターがプロパティアクセスとなるため、リスト7の(3)のコードとなります。

[リスト7]MemoListFragment.kt
val action = MemoListFragmentDirections.actionMemoListFragmentToMemoDetailFragment()  // (1)
action.memoId = memoId  // (3)
navController.navigate(action)  // (2)

遷移先でデータを受け取るJavaコード

 このようにして格納されたデータを、遷移先デスティネーションで受け取るコードは、Javaではリスト8のようになります。

[リスト8]MemoDetailFragment.java
MemoDetailFragmentArgs memoDetailFragmentArgs = MemoDetailFragmentArgs.fromBundle(getArguments());  // (1)
long memoId = memoDetailFragmentArgs.getMemoId();  // (2)

 リスト8のようにargumentタグが設定されたデスティネーションでは、そのデスティネーションクラス名の末尾にArgsをつけたクラスが自動生成されています。MemoDetailFragmentならば、MemoDetailFragmentArgsです。そして、このクラスの中に遷移元から渡されたデータが格納されることになっています。

 そこで、まず、このMemoDetailFragmentArgsオブジェクトを取得します。それが、リスト8の(1)です。〇〇Argsクラスには、staticメソッドとしてfromBundle()が自動生成されているので、このメソッドを利用します。その際、引数として、Bundleオブジェクトであるarguments、すなわち、getArguments()の戻り値を渡します。

 こうして取得した〇〇Argsオブジェクトには、argumentタグで設定したデータのゲッターが自動生成されているので、このゲッターを利用してデータを取得します。リスト8の(2)が、そのコードです。

遷移先でデータを受け取るKotlinコード

 一方、Kotlinコードは、Javaコードとは違うものとなり、リスト9のコードとなります。

[リスト9]MemoDetailFragment.kt
private val _memoDetailFragmentArgs: MemoDetailFragmentArgs by navArgs()  // (1)
override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  _memoDetailViewModel.memoId = _memoDetailFragmentArgs.memoId  // (2)
}

 Kotlinの場合は、〇〇Argsオブジェクトは、フラグメントクラスのプロパティとして定義します。それが、リスト9の(1)です。そして、navArgs()関数による委譲プロパティとして、インスタンスの用意を任せます。

 その後、任意のメソッド内で、〇〇Argsオブジェクトのプロパティを利用してデータを取得します。それが(2)です。リスト9では、onCreate()メソッド内で遷移元からのデータを取得し、ViewModelに格納するコード例としていますが、もちろん、他のメソッド内でも利用できます。

次のページ
Kotlin DSLによるナビゲーション定義

この記事は参考になりましたか?

一歩進んだAndroidアプリ開発ができる「Android Jetpack」入門連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト 齊藤 新三(サイトウ シンゾウ)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook <個人紹介>WINGSプロジェクト所属のテクニカルライター。Web系製作会社のシステム部門、SI会社を経てフリーランスとして独立。屋号はSarva(サルヴァ)。HAL大阪の非常勤講師を兼務。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/22755 2025/12/19 11:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング