Edited at

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