こんにちは、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の設定
dependencies {
classpath "android.arch.navigation:navigation-safe-args-gradle-plugin:1.0.0-alpha01"
...
}
repositories {
google()
...
}
app/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
nav_graph.xmlの編集
[Text]で表示してみるとnavigationタグは初めて見ますね!
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android">
</navigation>
[Design]で編集していきましょう。
プラス画像をクリック
↓
Create blank distinationをクリック
↓
Fragmentの名前とかxml layoutの作成、callbackの作成とか...etc
今回はLoginFragment,HomeFragment,ProfileFragment,SettingFragmentを作成
Navigationの遷移フローを追加していきます。
Login画面
↓
Home画面 → Profile画面
↓
Setting画面
になるようにGUIで操作していきます。
iOSのStoryboardに近いし感覚です。
Main Activity
ここで、FragmentはNavHostFragmentを指定します。
nav_graph.xmlに定義した情報をBindしてくれるみたいですね!
<?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>
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です。
<?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>
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