Help us understand the problem. What is going on with this article?

Navigation Architecture Component 使えそうな予感

More than 1 year has passed since last update.

こんにちは、m_saekiです。

Google I/O 2018で追加されたNavigation Architecture Component
を実装しました。

先に言わせていただきます。かなり便利です!!
今までだと、FragmentTransactionの処理が複雑難解になっていくプロジェクトをいくつも経験していましたが、「no more fragment transaction!!!」だそうです。
やってくれたぞGoogle様!!

何ができるかというと、名前の通りFragmentのNavigatinしてくれます!w
公式の言葉を借りると遷移処理の実装を簡単にしてくれます。
The Navigation Architecture Component simplifies the implementation of navigation in an Android app.

今回は、下記の画面構成をイメージして作っていきます。
Login画面

Home画面 → Profile画面

Setting画面

環境

Android Studio 3.2.1 (3.2 Preview版 必須)
Kotlin

builde.gradle

project/build.gradleの設定

build.gradle
dependencies {
        classpath "android.arch.navigation:navigation-safe-args-gradle-plugin:1.0.0-alpha01"

        ...
}
repositories {
        google()

        ...
}

app/build.gradleの設定

build.gradle
apply plugin: "androidx.navigation.safeargs"

dependencies {
    def nav_version = "1.0.0-alpha01"
    implementation "android.arch.navigation:navigation-fragment:$nav_version" // use -ktx for Kotlin
    implementation "android.arch.navigation:navigation-ui:$nav_version" // use -ktx for Kotlin

    ...
}

Navigation Resource

AndroidStudio3.2で新しく追加されたNavigation Resourceを追加

project内のresディレクトリで右クリック→NEW→AndroidResourceFileを選択し下記に設定しOKボタン
File name : nav_graph
Recource type : Navigation

スクリーンショット 2018-05-25 10.56.06.png

nav_graph.xmlの編集

[Text]で表示してみるとnavigationタグは初めて見ますね!

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android">

</navigation>

[Design]で編集していきましょう。
プラス画像をクリックスクリーンショット 2018-05-25 11.13.31.png

Create blank distinationをクリック

Fragmentの名前とかxml layoutの作成、callbackの作成とか...etc

スクリーンショット 2018-05-25 11.16.36.png

今回はLoginFragment,HomeFragment,ProfileFragment,SettingFragmentを作成

スクリーンショット 2018-05-25 11.32.39.png

Navigationの遷移フローを追加していきます。
Login画面

Home画面 → Profile画面

Setting画面
になるようにGUIで操作していきます。
iOSのStoryboardに近いし感覚です。

スクリーンショット 2018-05-25 11.36.48.png
これで遷移フローは完成です!

Main Activity

ここで、FragmentはNavHostFragmentを指定します。
nav_graph.xmlに定義した情報をBindしてくれるみたいですね!

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

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

</android.support.constraint.ConstraintLayout>
MacinActivity.kt
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }

    override fun onSupportNavigateUp()
            = findNavController(this, R.id.my_nav_host_fragment).navigateUp()
}

Fragment

クリック処理の中で次の遷移先を設定

Navigation.findNavController(view).navigate(R.id.action_loginFragment_to_homeFragment)

残りのFragmentも同じように実装すればOKです。

fragment_login.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#000"
    tools:context=".LoginFragment">

    <Button
        android:id="@+id/login_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="login"/>

</FrameLayout>
LoginFragment.kt
class LoginFragment : Fragment() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        // Inflate the layout for this fragment
        var view = inflater.inflate(R.layout.fragment_login, container, false)
        var button = view.findViewById<Button>(R.id.login_button);
        button.setOnClickListener { view ->
            Navigation.findNavController(view).navigate(R.id.action_loginFragment_to_homeFragment)
        }
        return view
    }
}

参考URL

https://developer.android.com/topic/libraries/architecture/navigation/navigation-implementing

m_saeki
Android,iOSアプリエンジニアです。 今はサーバサイド勉強中。
http://landland.tech/
landland
スマートフォンアプリを開発・運営するスタートアップ
https://landland.tech/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away