Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Navigation - Android Architecture Components
Search
Daichi Furiya (Wasabeef)
July 18, 2019
Programming
6
8.7k
Navigation - Android Architecture Components
Introduction to Navigation components
Daichi Furiya (Wasabeef)
July 18, 2019
Tweet
Share
More Decks by Daichi Furiya (Wasabeef)
See All by Daichi Furiya (Wasabeef)
About Flutter Architecture
wasabeef
0
150
2023 Flutter/Dart Summary
wasabeef
0
42
I/O Extended 2023 - Dart と Flutter の新機能
wasabeef
0
130
I/O Extended 2023 - Flutter 活用事例
wasabeef
11
2.7k
What it Takes to be a Flutter Developer
wasabeef
0
150
FlutterKaigi 2022 Keynote
wasabeef
1
540
Flutter Hooks を使ったアプリ開発 / App Development with the Flutter Hooks
wasabeef
2
1.3k
Flutter 2021 の振り返りと今後のアプリ開発に向けて / Looking back on Flutter 2021 and for future app development.
wasabeef
4
2.1k
Flutter Hooks, sometimes Jetpack Compose
wasabeef
3
1.7k
Other Decks in Programming
See All in Programming
What’s New in Compose Multiplatform - A Live Tour (droidcon London 2024)
zsmb
1
350
qmuntal/stateless のススメ
sgash708
0
120
Universal Linksの実装方法と陥りがちな罠
kaitokudou
1
220
Tuning GraphQL on Rails
pyama86
2
1k
役立つログに取り組もう
irof
27
8.7k
Java ジェネリクス入門 2024
nagise
0
610
推し活の ハイトラフィックに立ち向かう Railsとアーキテクチャ - Kaigi on Rails 2024
falcon8823
6
2.2k
offers_20241022_imakiire.pdf
imakurusu
2
360
デプロイを任されたので、教わった通りにデプロイしたら障害になった件 ~俺のやらかしを越えてゆけ~
techouse
52
32k
Modern Angular: Renovation for Your Applications
manfredsteyer
PRO
0
210
/←このスケジュール表に立ち向かう フロントエンド開発戦略 / A front-end development strategy to tackle a single-slash schedule.
nrslib
1
590
Webの技術スタックで マルチプラットフォームアプリ開発を可能にするElixirDesktopの紹介
thehaigo
2
920
Featured
See All Featured
Reflections from 52 weeks, 52 projects
jeffersonlam
346
20k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
14
1.9k
Speed Design
sergeychernyshev
24
570
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
167
49k
Writing Fast Ruby
sferik
626
61k
Bootstrapping a Software Product
garrettdimon
PRO
305
110k
KATA
mclloyd
29
13k
Code Review Best Practice
trishagee
64
17k
Why You Should Never Use an ORM
jnunemaker
PRO
53
9k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
131
33k
The Straight Up "How To Draw Better" Workshop
denniskardys
232
140k
Stop Working from a Prison Cell
hatefulcrawdad
267
20k
Transcript
Architecture Components ษڧձ ͋Μ͍͟Ώ͖ ͕͑Θ Θ͞ͼʔ; ͋Β͖ ୈ8ճ Navigation
Architecture Components ษڧձ ͱ • Architecture Components ͷجૅࣝʹֶ͍ͭͯͿษڧձ • ओ࠵ɿGDG
Tokyo ϋογϡλά: #gdgtokyo • ߨࢣɺνϡʔλʔɿGoogle ࣾһͱ Google Developer Expert • ʢ͋Μ͍͟Ώ͖ɺ ͕͑ΘɺΘ͞ͼʔ;ɺ͋Β͖ʣ • νϡʔλʔ : @95kugo, @STAR_ZERO, @tomoya0x00
Architecture Components ษڧձ ͱ • ܭ4ճͷ༧ఆ • ୈ5ճ: Lifecycle, ViewModel,
LiveData ͷ෮श • ୈ6ճ: Room ͷ෮श, Paging • ୈ7ճ: WorkManager • ୈ8ճ: Navigation λΠϜςʔϒϧ 19:30ʙ19:35 ѫࡰˍઆ໌ 19:35ʙ20:15 આ໌ 20:15ʙ20:25 ٳܜ 20:25ʙ ՝औΓΈ
Architecture Components ͱ ෳͷػೳɾϥΠϒϥϦͷ૯শ • Data Binding • Lifecycles •
LiveData • ViewModel • Room • Paging • WorkManager • Navigation
Architecture Components ͱ ෳͷػೳɾϥΠϒϥϦͷ૯শ • Data Binding • Lifecycles •
LiveData • ViewModel • Room • Paging • WorkManager • Navigation ݸผར༻OK Έ߹Θͤར༻OK
Architecture Components ͱ ෳͷػೳɾϥΠϒϥϦͷ૯শ • Data Binding • Lifecycles •
LiveData • ViewModel • Room • Paging • WorkManager • Navigation ݸผར༻OK Έ߹Θͤར༻OK #1 #2 #3 #4
Architecture Components ͱ ෳͷػೳɾϥΠϒϥϦͷ૯শ • Data Binding • Lifecycles •
LiveData • ViewModel • Room • Paging • WorkManager • Navigation ݸผར༻OK Έ߹Θͤར༻OK #1 #2 #3 #4 #5 #6 #7 #8
Architecture Components ͷత ݎ࿚ (robust) Ͱ ςετ͘͢͠ (testableʣ อक͍͢͠ (maintainable)
ΞϓϦͷઃܭ͕Ͱ͖ΔΑ͏ʹखॿ͚͢Δ
Navigation
Navigation • Fragment Transaction ͷ؆қԽ • Ξχϝʔγϣϯ • σΟʔϓϦϯΫ •
BottomNavigation / Toolbar ͳͲͱ؆୯ʹ࿈ܞ • Fragment ؒͰσʔλΛܕ҆શʹͤΔ • Navigation editor Λ͏ͱ GUI Ͱ؆୯ʹઃఆ͕Ͱ͖Δ
Navigation
Gradle - dependencies dependencies { def nav_version = "2.1.0-alpha06" implementation
“androidx.navigation:navigation-fragment-ktx:nav_version" implementation “androidx.navigation:navigation-ui-ktx:nav_version” }
Gradle - dependencies buildscript { repositories { google() } dependencies
{ def nav_version = "2.1.0-alpha06" classpath “androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version" } } "// Kotlin apply plugin: "androidx.navigation.safeargs.kotlin"
Basic • ͜͜Ͱɺ؆୯ͳ Navigation editor ͷ͍ํཁૉͷઆ໌Λͯ͠ ͍͖·͢ɻ
nav_graph.xml • res/navigation ͷԼʹ Navigation ༻ ͷ xml Λ࡞Γɺ։͍ͯݟ͍ͯͩ͘͞ɻ ※
͜͜Ͱ nav_graph.xml ͱ͠·͢
nav_graph.xml Destinations panel
nav_graph.xml Graph Editor
nav_graph.xml Attributes
nav_graph.xml GUI ্Ͱ֤ը໘ΛՃ͢Δ߹ʹɺ ͜ͷϘλϯ͔Β؆୯ʹՃͰ͖·͢ɻ
Demo: Navigation editor
nav_graph.xml Ͱར༻͢Δओͳλά • <navigation /> : ϧʔτཁૉɻىಈޙͷ։࢝ҐஔͳͲΛࢦఆ • <fragment />
: ֤ը໘ʢFragmentʣ • <action /> : ը໘ؒͷ֤ը໘ʢFragmentʣ • <argument /> : ը໘Ͱड͚औΔҾ • <deeplink /> : σΟʔϓϦϯΫ • <dialog /> : DialogFragmentΛར༻͍ͯ͠Δ߹ͷը໘ • <include /> : Nested graphsɻάϥϑΛׂͯ͠ཧɾ࠶ར༻
nav_graph.xml <?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" xmlns:tools="http:"//schemas.android.com/tools" android:id="@+id/nav_graph" app:startDestination="@id/fragment_home">
<fragment android:id="@+id/fragment_home" android:name="jp.wasabeef.navplayground.home.HomeFragment" tools:layout="@layout/fragment_home"> <action android:id="@+id/to_dashboard" app:destination="@id/fragment_dashboard""/> "</fragment> <fragment android:id="@+id/fragment_dashboard" android:name="jp.wasabeef.navplayground.dashboard.DashboardFragment" tools:layout="@layout/fragment_dashboard" > <argument android:name="id" app:argType="string" "/> "</fragment> "</navigation> ֤λάΛઆ໌͍͖ͯ͠·͢ɻ
<navigation /> <?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/nav_graph"> "</navigation>
ϧʔτཁૉʹͳΓ·͢ ͜ͷதʹ֤λάΛهࡌ͖ͯ͠·͢ɻ ޙड़͠·͕͢ɺىಈ࣌ͷॳظը໘ͷઃఆ͜͜ʹ͠·͢
<fragment /> <?xml version="1.0" encoding="utf-8"?> <navigation ""... app:startDestination="@id/fragment_home"> <fragment android:id="@+id/fragment_home"
android:name="jp.wasabeef.navplayground.home.HomeFragment" android:label="HomeFragment" tools:layout="@layout/fragment_home"> "</fragment> "</navigation> ͜ͷλάͰ Fragment ͷ֘Ϋϥεͱࢦఆ͠·͢ ·ͨɺޙड़͠·͕͢ <action/>, < argument/>, <deeplink/> ͳͲ͜ͷԼʹهࡌ͠·͢ɻ
<?xml version="1.0" encoding="utf-8"?> <navigation ""... app:startDestination="@id/fragment_home"> <fragment android:id="@+id/fragment_home" android:name="jp.wasabeef.navplayground.home.HomeFragment" android:label="HomeFragment"
tools:layout="@layout/fragment_home"> "</fragment> "</navigation> <fragment /> ͜ͷ HomeFragment Λىಈ࣌ͷॳظը໘ͱ͢Δ߹ <navigation/> ͷ startDestination ʹࢦఆ͠·͢
<fragment /> GUI ্ͩͱɺ͜ͷҰͭʹ֘͠·͢ɻ
<argument /> <?xml version="1.0" encoding="utf-8"?> <navigation ""...> <fragment android:id="@+id/fragment_dashboard" android:name="jp.wasabeef.navplayground.dashboard.DashboardFragment"
android:label="DashboardFragment" tools:layout="@layout/fragment_dashboard" > <argument android:name="id" app:argType="string" "/> "</fragment> "</navigation> Ҿʹ integer, float, long, boolean, string, reference, parcelable, serializable, enum ͷར༻͕Մೳ ར༻Ͱ͖Δܕɿhttps://developer.android.com/guide/navigation/navigation-pass-data#supported_argument_types
<action /> <?xml version="1.0" encoding="utf-8"?> <navigation ""...> <fragment ""...> <action
android:id="@+id/to_dashboard" app:destination="@id/fragment_dashboard""/> "</fragment> <fragment android:id=“@+id/fragment_dashboard" ""..."/> "</navigation> <action> ͰॏཁʹͳΔͷ͕ id ͱ destination Ͱ͢ɻ id setOnClickListener ͳͲͰࢦఆ͢Δͱ͖ʹ ͍ɺdestination ભҠઌͷ Fragment Λࢦఆ͠·͢
<action /> with anim ભҠ࣌ͷΞχϝʔγϣϯΛՃ͢Δ߹ɺ͜ͷΑ͏ʹͳΓ·͢ɻ <action android:id="@+id/to_dashboard" app:destination="@id/fragment_dashboard" app:enterAnim="@anim/nav_default_enter_anim" app:exitAnim="@anim/nav_default_exit_anim"
app:popEnterAnim="@anim/nav_default_pop_enter_anim" app:popExitAnim="@anim/nav_default_pop_exit_anim" "/>
<deeplink /> <fragment android:id="@+id/fragment_dashboard" android:name="jp.wasabeef.navplayground.dashboard.DashboardFragment" android:label="DashboardFragment" tools:layout="@layout/fragment_dashboard" > <argument android:name="id"
app:argType="string" "/> <deeplink android:id="@+id/deeplink" app:uri="wasabeef.jp/dashboard/{id}" "/> "</fragment> σΟʔϓϦϯΫͰىಈ͍ͨ͠ Fragment ͷԼ ʹىಈ͢Δ URIɺҾ Λઃఆ͠·͢ɻ
<deeplink /> - AndroidManifest.xml AndroidManifest ʹ <intent-filter/> Ͱͳ͘ <nav-graph/> ΛՃ͢Δ͜ͱͰɺ͜͜ͷઃఆ
݁ͳΓ·͢ <?xml version="1.0" encoding="utf-8"?> <manifest ""...> <application ""...> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" "/> <category android:name="android.intent.category.LAUNCHER" "/> "</intent-filter> <nav-graph android:value="@navigation/nav_graph" "/> "</activity> "</application> "</manifest>
<dialog /> <?xml version="1.0" encoding="utf-8"?> <navigation ""...> <fragment ""...> <action
android:id="@+id/show_confirm" app:destination=“@id/fragment_confirm_dialog""/> "</fragment> <dialog android:id=“@+id/fragment_confirm_dialog” ""..."/> "</navigation> ͍ํ <fragment/> ͱಉ͡Ͱ DialogFragment Λ Navigation Ͱར༻͍ͨ͠߹ͪ͜ΒΛ͍·͢ɻ
NavHostFragment <fragment android:id="@+id/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" "/> activity_main.xml
ʹը໘੍ޚ͢Δ NavHostFragment Λઃఆ͠ɺ࡞ͨ͠ nav_graph.xml Λࢦఆ͢Δඞཁ͕͋Γ·͢ɻ
Advanced • Nested navigation graph • BottomNavigation • FragmentNavigator
Nested navigation graphs ͜ΕʹΑΓ͜Ε·Ͱ̍ͭͷ xml Ͱ ̍ͭͷ Activity ͕ભҠ͢Δ Fragment
ͷઃఆ͕શׂͯɾ࠶ར༻Ͱ͖ΔΑ͏ʹͳΓ·͠ ͨɻ
<?xml version="1.0" encoding="utf-8"?> <navigation""...> <include app:graph="@navigation/included_graph" ""... "</navigation> Nested navigation
graphs ଞͷάϥϑΛ <include/> ͢Δ͜ͱ͕Ͱ͖·͢ɻ
Z BottomNavigation "// MainActivity override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main) val navController = findNavController(R.id.nav_host_fragment) "// ActionBarͷλΠτϧͳͲΛ੍ޚ setupActionBarWithNavController( navController, AppBarConfiguration( setOf( R.id.fragment_home, R.id.fragment_dashboard ) ) ) "// ભҠΛ੍ޚ nav_view.setupWithNavController(navController) } ͜Ε͚ͩͰ BottomNavigation ͱͷ࿈ܞՄೳ <!— activity_main.xml —> <com.google.android.material.bottomnavigation.BottomNavigationView android:id="@+id/nav_view" app:menu="@menu/bottom_nav_menu" ""..."/> <!— bottom_nav_menu.xml ※ nav_graph.xml ͷ <fragment "/>Ͱࢦఆ͢Δ Id ͱҰகͤ͞Δ —> <menu ""...> <item android:id="@+id/fragment_home" …"/> <item android:id=“@+id/fragment_dashboard" ""..."/> "</menu>
FragmentNavigator nav_graph.xml ͰΧελϜλάΛ࡞ΕΔ Α͏ʹͳΓ·͢ɻ <fragment_with_anim android:id="@+id/fragment_home" android:name="jp.wasabeef.navplayground.home.HomeFragment" android:label="HomeFragment" tools:layout="@layout/fragment_home"> <action
android:id="@+id/to_dashboard" app:destination="@id/fragment_dashboard" "/> "</fragment_with_anim>
FragmentNavigator ͜ΕʹΑΓ͜Ε·Ͱ̍ͭͷ xml Ͱ ̍ͭͷ Activity ͕ભҠ͢Δ Fragment ͷઃఆ͕શׂͯɾ࠶ར༻Ͱ͖ΔΑ͏ʹͳΓ·͠ ͨɻ
@Navigator.Name("fragment_with_anim") class DefaultNavigator( context: Context, manager: FragmentManager, containerId: Int ) : FragmentNavigator(context, manager, containerId) { override fun navigate( destination: Destination, args: Bundle?, navOptions: NavOptions?, navigatorExtras: Navigator.Extras? ): NavDestination? { return super.navigate(destination, args, exOp, navigatorExtras) } }
FragmentNavigator MainActivity Ͱ ࡞ͨ͠ FragmentNavigator Λ NavController ʹՃ͠·͢ɻ ※ άϥϑ͕ઃఆ͞ΕΔલʹɺߦΘͳ͍ͱ͍͚·ͤΜɻ
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) findNavController(R.id.nav_host_fragment).apply { navigatorProvider += DefaultNavigator( this@MainActivity, nav_host_fragment.childFragmentManager, R.id.nav_host_fragment ) setGraph(R.navigation.nav_graph) } }
՝
՝0 • ՝Ͱ͏ίʔυͪ͜ΒͰ͢ɻ https://github.com/wasabeef/NavPlayground git clone
[email protected]
:wasabeef/NavPlayground.git
Ϟδϡʔϧߏ app-step0 = ࡞ۀ༻Ϟδϡʔϧ
՝ • ՝1 Navigation Խͯ͠ɺHome -> DashboardΛભҠͤ͞·͠ΐ͏ɻ ՝1.5 ભҠ࣌ͷΞχϝʔγϣϯΛՃͯ͠Έ·͠ΐ͏ɻ •
՝2 <argument /> Λͬͯ Dashboard ʹ id:String, name:String, location:String Λͯ͠Έ·͠ΐ͏ɻ • ՝3 <deeplink /> Λͬͯ Dashboard ͕͜ͷURLͰىಈͰ͖ΔΑ͏ʹ͠·͠ΐ͏ɻ https://sample.com/dashboard/{id}/{name} ىಈςετɿ adb shell am start -W -a android.intent.action.VIEW \ -d "https://sample.com/dashboard/xxxxx/yyyyy"
՝ʢ͕࣌ؒ͋Εʣ • ՝4 <include/> ΛͬͯάϥϑΛׂͯ͠Έ·͠ΐ͏ɻ • ՝5 BottomNavigation ͷ࣮Λ Navigation
ΛͬͯΈ·͠ΐ͏ɻ
͑ • ՝1 -> app-step1-action, app-step1-action-with-anim • ՝2 -> app-step2-args
• ՝3 -> app-step3-deeplink • ՝4 -> app-step4-nested • ՝5 -> app-step5-bottom-nav • ՝6 -> app-step6-navigator
ࢀߟࢿྉ • Android Navigation Architecture Component https://medium.com/@Alex.v/android-navigation-architecture- component-25b5a7aab8aa • Get
started with the Navigation component https://developer.android.com/guide/navigation/navigation-getting- started •