見出し画像

【Androidアプリ開発】 便利なライブラリ Navigation

こんにちは。ぽつぽです。

今回は、Androidアプリ開発で普段お世話になっている、Navigationのご紹介です。
Androidアプリ開発をやっている人なら、一度は聞いたり使用されている方もいらっしゃるのではないでしょうか?

今回もサンプルアプリを作成したので、気になる方はこちらもチェック!

サンプルアプリの機能は以下の通りです。
・メイン画面で設定した2つ値を四則演算を行い、遷移先の画面で結果を表示する
・画面遷移時に、フェードイン、フェードアウトのアニメーションを行う

実際のアプリ動作は、動画でチェック!

も く じ

・Navigationとは?
・Navigationを使用した画面遷移のやり方
・アニメーションのつけかた

Navigationとは?

簡単に言うと、JetPackで用意されている画面遷移のためのライブラリです。

Fragment間の画面遷移や値の受け渡しに苦労した方もいらっしゃるのではないでしょうか?

私も入社当時は、Fragment間の値の受け渡しに苦労しておりました。
Navigationは、そんな悩みを解決するすごく便利なライブラリです。

Navigationを使用した画面遷移のやり方

では、これから実際の実装方法についてご説明します。
*以下のコードは、すべて上記のサンプルアプリに記載されているので、
 わかりづらい時は、コードを見てください。

** 5ステップで実装 **

1. build.gradle の設定

追加するものは、主に2つです。
ここでは、dataBiningというUIのためのライブラリとNavigationライブラリを追加します。
safeargsというものは、画面遷移時の値の受け渡しで使用するものです。

/* build.gradle (Module: app) */

...省略
apply plugin: 'kotlin-kapt' // 追加
apply plugin: 'androidx.navigation.safeargs' // 追加

android {
   ...省略
   // 追加
   dataBinding {
       enabled = true
   }
   // 追加
   kotlinOptions {
       jvmTarget = '1.8'
   }
}

dependencies {
   ...省略

   // Navigation
   implementation 'androidx.navigation:navigation-fragment-ktx:2.3.0' // 追加
   implementation 'androidx.navigation:navigation-ui-ktx:2.3.0' // 追加
}
/* build.gradle (Project) */

buildscript {
   ...省略
   dependencies {
       ...省略
       // Navigation safe args (追加)
       classpath 'android.arch.navigation:navigation-safe-args-gradle-plugin:1.0.0'
   }
}

...省略

2. 遷移グラフの追加

今回は、画面の作成は省きます。
とりあえず、画面遷移だけ試したい方はサンプルアプリのコードをご使用ください。

2-1. resフォルダ内に、navigationフォルダを作成する
さらにnavigationフォルダ内にnavigationのXMLファイルを作りましょう。
*XMLファイル名は、「main_nav_graph」にしました。

画像1

2-2. 遷移グラフの作成
以下、XMLファイルのコードです。
ここでは、受け渡す値の型の設定(argument)、遷移先の画面の設定(action)、遷移時のアニメーションの設定(〇〇Anim)を行います。
4行目の"app:startDestination"で、はじめに読み出される画面を設定します。

<?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"
   android:id="@+id/main_nav_graph"
   app:startDestination="@id/mainFragment">

   <fragment
       android:id="@+id/mainFragment"
       android:name="jp.com.hatenablog.hiropoppo.calculationapp.MainFragment"
       android:label="MainFragment">
       <action
           android:id="@+id/action_mainFragment_to_resultFragment"
           app:destination="@id/resultFragment"
           app:enterAnim="@anim/slide_from_right"
           app:exitAnim="@anim/slide_to_left"
           app:popEnterAnim="@anim/slide_from_left"
           app:popExitAnim="@anim/slide_to_right" />
   </fragment>

   <fragment
       android:id="@+id/resultFragment"
       android:name="jp.com.hatenablog.hiropoppo.calculationapp.ResultFragment"
       android:label="ResultFragment">
       <argument
           android:name="result"
           app:argType="string" />
   </fragment>
</navigation>

↑ここまで完成したら、必ずビルドしてください!↑

3. MainActivityへの紐つけ
続いては、今しがた作ったnavigationファイルをFragmentの受け皿となるMainActivityに紐づけておきます。
activity_main.xmlに以下のコードを追加しましょう。

<fragment
    android:id="@+id/nav_host_fragment"
    android:name="androidx.navigation.fragment.NavHostFragment"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    app:defaultNavHost="true"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:navGraph="@navigation/main_nav_graph"
    tools:ignore="FragmentTagUsage" />

はい、紐つけは以上です。

って「あれ?MainActivityで設定しないでいいの?」と思われたかもしれませんが、大丈夫です!

Navigationを使用した場合、XMLファイルで完結します。
余計なコードを書かなくて済むので、すごく便利ですね👍

4. 画面遷移と値の受け渡し

/* MainFragmentの65行目 */
activity?.findNavController(R.id.nav_host_fragment)
               ?.navigate(MainFragmentDirections.actionMainFragmentToResultFragment(result.toString()))

コードはこれだけです(短い!)
"actionMainFragmentToResultFragment"というものを呼び出しております。
これは、遷移グラフで設定したactionのIDになります。
そして、括弧内に次の画面に渡したい値をセットします。

5. 値の取得
それでは、最後に値の取得方法についてです。
まずは、値を取得するための変数を追加します。(ポイント1)
続いて、ポイント2で遷移元から渡ってきた値を参照しております。
args + result となっておりますが、末尾のresultは遷移グラフのargumentで設定したnameの名前になります。

/**
* 計算結果画面
*/
class ResultFragment : Fragment() {

   //region MARK: - private fields
   private lateinit var binding: FragmentResultBinding
   private val args: ResultFragmentArgs by navArgs() // <------- ポイント1
   //endregion

   //region MARK: - fragment lifeCycle method
   override fun onCreateView(
       inflater: LayoutInflater, container: ViewGroup?,
       savedInstanceState: Bundle?
   ): View? {
       binding = FragmentResultBinding.inflate(inflater, container, false)
       binding.lifecycleOwner = this

       binding.result.text = args.result // <-------- ポイント2
       
       binding.backButton.setOnClickListener { findNavController().navigateUp() }
       return binding.root
   }
   //endregion
}

まとめ

さて、いかがだったでしょうか?
今回はNavigationについてご紹介いたしました。

私がはじめて出会った時はすごく衝撃的で、
「こんなに簡単にかけるんだ!」と喜んだものです。

Fragment間の画面遷移、値の受け渡しで苦戦している方は、
是非使ってみてはいかがでしょうか?

それでは、また次回です。
ありがとうございました マタネー