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)
DevFest Tokyo 2025 - Flutter のアプリアーキテクチャ現在地点
wasabeef
5
900
About Flutter Architecture
wasabeef
0
170
2023 Flutter/Dart Summary
wasabeef
0
46
I/O Extended 2023 - Dart と Flutter の新機能
wasabeef
0
140
I/O Extended 2023 - Flutter 活用事例
wasabeef
10
2.8k
What it Takes to be a Flutter Developer
wasabeef
0
160
FlutterKaigi 2022 Keynote
wasabeef
1
560
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
Other Decks in Programming
See All in Programming
テストケースの名前はどうつけるべきか?
orgachem
PRO
0
130
コンテナをたくさん詰め込んだシステムとランタイムの変化
makihiro
1
130
42 best practices for Symfony, a decade later
tucksaun
1
180
The Efficiency Paradox and How to Save Yourself and the World
hollycummins
1
440
Effective Signals in Angular 19+: Rules and Helpers @ngbe2024
manfredsteyer
PRO
0
140
複雑な仕様に立ち向かうアーキテクチャ
myohei
0
170
Semantic Kernelのネイティブプラグインで知識拡張をしてみる
tomokusaba
0
180
nekko cloudにおけるProxmox VE利用事例
irumaru
3
430
数十万行のプロジェクトを Scala 2から3に完全移行した
xuwei_k
0
270
create_tableをしただけなのに〜囚われのuuid編〜
daisukeshinoku
0
240
なまけものオバケたち -PHP 8.4 に入った新機能の紹介-
tanakahisateru
1
120
Stackless и stackful? Корутины и асинхронность в Go
lamodatech
0
750
Featured
See All Featured
Java REST API Framework Comparison - PWX 2021
mraible
PRO
28
8.3k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
47
5.1k
Intergalactic Javascript Robots from Outer Space
tanoku
270
27k
The Illustrated Children's Guide to Kubernetes
chrisshort
48
48k
Facilitating Awesome Meetings
lara
50
6.1k
Fontdeck: Realign not Redesign
paulrobertlloyd
82
5.3k
The Cult of Friendly URLs
andyhume
78
6.1k
Become a Pro
speakerdeck
PRO
26
5k
Testing 201, or: Great Expectations
jmmastey
40
7.1k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
247
1.3M
Done Done
chrislema
181
16k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
95
17k
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 •