๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

Android & Kotlin

Lesson 3: App Navigation

Udacity ์—์„œ Developing Android Apps with Kotlin ์ด๋ผ๋Š” ๊ฐ•์˜๋ฅผ ๋“ฃ๊ณ  lesson ๋ณ„๋กœ ์ค‘์š”ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•œ ๋ถ€๋ถ„์„ ํ•„๊ธฐํ•œ ๋‚ด์šฉ์ด๋‹ค. 
์˜์–ด ๊ฐ•์˜๋ฅผ ๋“ฃ๊ณ  ํ•„๊ธฐํ•œ ๋‚ด์šฉ์ด๋‹ค ๋ณด๋‹ˆ ๋ฒˆ์—ญ์ด๋‚˜ ํ•ด์„์ด ์ž˜๋ชป๋œ ๋ถ€๋ถ„์ด ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค. ๋˜ ์ผ๋ถ€๋Š” ์˜์–ด ๋‹จ์–ด๋‚˜ ๋ฌธ์žฅ์„ ๊ทธ๋Œ€๋กœ ์ ์–ด๋†“์•˜๋‹ค. 
์ •ํ™•ํ•œ ๋‚ด์šฉ์€ ๊ฐ•์˜๋ฅผ ์ง์ ‘ ์ฐธ๊ณ ํ•˜๋Š” ๊ฒƒ์„ ๊ถŒํ•œ๋‹ค.

 

Developing Android Apps with Kotlin | Udacity Free Courses

Take Udacity's free online course and learn Android development with Kotlin. Master the fundamentals of the Kotlin programming language taught by Kotlin experts at Google.

www.udacity.com


3. Quiz: Navigation Terms

4. Fragments

Android introduced fragments in Android 3.0 API level 11, primarily to support more dynamic and flexible UI designs on large screens such as tablets. The activity operates as a frame that contains the UI fragments and can provide UI elements that surround the fragment. UI fragment’s generally operate like a view within the activity’s layout, but like in activity, you must create a subclass of fragment to use it. This gives you a layout along with the convenient place to put UI logic, the foundation of a reusable UI component. With fragments, You can pretty much treat activities as the operating system’s entry point to the app. Since most of your UI ends up being implemented in the fragments, but the OS can only open activities. Within an activity, You tell Android which layout to use by calling setContentView in onCreate. The activity then inflates the layout and places it correctly within the activity’s layout hierarchy. With fragments, you manually inflate and return the inflated layout within the onCreate view method, which is independent of  onCreate. Another difference, since activities inherit from the context class, but fragments do not, you'll need to use the context property within a fragment to have access to app data typically associated with the context, such as string and image resources. 

OK, now we are ready to talk about navigation. You can navigate between different activities and between fragments and activity. As you navigate through activities in Android, the previous activities from within the app as well as from previous apps are arranged in a stack that we call the back stack. This back stack is ordered based upon the order in which each activity is opened. An application that has a title screen as the first screen followed by a trivia game activity would have the trivia game activity at the top of the stack, hitting the system back key would pop the trivia game activity off the stack and return to the title screen activity and hitting it again would exit the app, finishing the activity and return us to the previous app, probably the launcher. Fragments can have a similar backstack, except that entire stack is contained within the activity. All of this is controlled by a class called the fragment manager. When a fragment is instantiated by the fragment manager, the fragment transaction can optionally be added to the fragment back stack. If our example trivia app was written using fragments and we run the game screen, the fragment backstack would contain a transaction to return us to the title screen fragment. Hitting the back key would execute this transaction, effectively popping the game screen fragment off of the stack and replacing it with a title screen fragment. Hitting it again would pass the back operation through to the activity backstack, finishing the activity and exiting the app. Ultimately, you can design your navigation with either an activity containing a series of fragments, a series of activities, or a combination of both techniques. For this class we're focusing on the single activity multiple fragment model which allows you to visualize your entire apps navigation within a single graph the best way to learn about fragments is to implement them which we're going to do in the project for this lesson.

5. Quiz: Fragment Basics

  • Fragment์—์„œ๋Š” activity์ฒ˜๋Ÿผ onCreate ๋ฉ”์†Œ๋“œ ๋‚ด์—์„œ view๋ฅผ inflate ์‹œํ‚ค๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ onCreateView ๋ฉ”์†Œ๋“œ ๋‚ด์—์„œ inflate ์‹œํ‚จ๋‹ค. 
  • Context property๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ string์ด๋‚˜ image resource ๊ฐ™์€ ์•ฑ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•œ๋‹ค.
  • UI Fragment๋Š” Activity layout ๋‚ด์— ํฌํ•จ๋˜๊ณ  ์ž๋ฆฌ๋ฅผ ์ฐจ์ง€ํ•œ๋‹ค. 

7. Exercise: Creating and Adding a Fragment (์ถ”๊ฐ€ ํ•„์š”)

Activity์—์„œ๋Š” DataBindingUtil.setContentView๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ ˆ์ด์•„์›ƒ์œผ๋กœ๋ถ€ํ„ฐ binding ํด๋ž˜์Šค๋ฅผ ๊ฐ€์ ธ์˜ด.
Fragment์—์„  DataBindingUtil.inflate๋ฅผ onCreateView ๋‚ด์—์„œ ํ˜ธ์ถœ.

10. Navigation Components

์›์น™ 1๏ธโƒฃ: There's Always a Starting Place
์•ฑ์€ ๊ณ ์ •๋œ ์ถœ๋ฐœ์ ์ด ์žˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ๋Ÿฐ์ฒ˜์—์„œ ์•ฑ์„ ์—ด์—ˆ์„ ๋•Œ, ์‚ฌ์šฉ์ž๊ฐ€ ๋’ค๋กœ๊ฐ€๊ธฐ ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์„ ๋•Œ ๋Ÿฐ์ฒ˜๋กœ ๋Œ์•„๊ฐ€๋Š” ํ™”๋ฉด. 

์›์น™ 2๏ธโƒฃ: You Can Always Go Back
์•ฑ์˜ ๋„ค๋น„๊ฒŒ์ด์…˜ state๋Š” LIFO๊ตฌ์กฐ๋ฅผ ๋”ฐ๋ผ์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ธ๋ฐ ์ด๊ฒƒ์ด ์•ž์—์„œ ์–ธ๊ธ‰๋œ backstack. Stack์˜ ๋ฐ”๋‹ฅ์—๋Š” start destination, stack์˜ ์ตœ์ƒ๋‹จ์—๋Š” current destination. ๋„ค๋น„๊ฒŒ์ด์…˜ ์Šคํƒ์„ ๋ณ€๊ฒฝํ•˜๋Š” ๋™์ž‘์€ ์Šคํƒ์˜ ์ตœ์ƒ๋‹จ์—์„œ๋งŒ ์ด๋ฃจ์–ด์ ธ์•ผํ•œ๋‹ค. 1) ์ƒˆ๋กœ์šด destination์„ ์ƒ๋‹จ์— push, 2) ์ƒ๋‹จ์˜ destination์„ ์Šคํƒ์—์„œ pop off.   

์›์น™ 3๏ธโƒฃ: Up goes Back(Mostly)
Action bar์˜ up button๊ณผ System์˜ back button์€ ์•ฑ ๋‚ด์—์„œ ์ด๋™ํ•  ๋•Œ ๋™์ผํ•˜๊ฒŒ ๋™์ž‘ํ•œ๋‹ค. System์˜ back button์€ ์•ฑ์˜ ์™ธ๋ถ€ ๋‹ค๋ฅธ ์•ฑ์ด๋‚˜ ๋ณดํ†ต ๋Ÿฐ์ฒ˜๋กœ ๋‚˜๊ฐ„๋‹ค. ์•ฑ์˜ ์‹œ์ž‘ํ™”๋ฉด์—์„œ๋Š” action bar์— up button์ด ๋ณด์—ฌ์ ธ์„œ๋Š” ์•ˆ๋œ๋‹ค.  

์ด๋Ÿฌํ•œ ์›์น™๋“ค์„ ์ ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž์—๊ฒŒ ์ผ๊ด€๋˜๊ณ  ์˜ˆ์ƒ ๊ฐ€๋Šฅํ•œ ๊ฒฝํ—˜์„ ์ œ๊ณตํ•ด์•ผํ•œ๋‹ค. 

12. Exercise: Back Stack Manipulation

Navigation Controller๋Š” back stack์„ ์ฒ˜๋ฆฌํ•ด์ค€๋‹ค. ์šฐ๋ฆฌ๊ฐ€ destination์œผ๋กœ ์ด๋™ํ•  ๋•Œ๋งˆ๋‹ค navigation controller๋Š” ๊ฐ destination์„ back stack์— ์ž๋™์œผ๋กœ ์ถ”๊ฐ€ํ•œ๋‹ค. 

์ด๊ฒƒ์ด ๋ฌธ์ œ๊ฐ€ ๋  ์ˆ˜ ์žˆ๋Š” ์ƒํ™ฉ์€ ์˜ˆ๋ฅผ ๋“ค์–ด TitleFragment(๊ฒŒ์ž„ ์‹œ์ž‘ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅผ ์ˆ˜ ์žˆ๋Š” ํ™”๋ฉด), GameFragment(๊ฒŒ์ž„์„ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ํ™”๋ฉด), GameOverFragment(๊ฒŒ์ž„ ์ข…๋ฃŒ๋ฅผ ์•Œ๋ฆฌ๋Š” ํ™”๋ฉด) ์ด ์ˆœ์„œ๋กœ ์ง„ํ–‰ํ•ด ์™”๋‹ค๊ณ  ํ–ˆ์„ ๋•Œ back key๋ฅผ ๋ˆ„๋ฅด๋ฉด ๋‹ค์‹œ GameFragment๋กœ ๋Œ์•„๊ฐ„๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ๊ฒŒ์ž„์ด ์ด๋ฏธ ์ข…๋ฃŒ๋œ ์ƒํƒœ์—์„œ ๋‹ค์‹œ GameFragment๋กœ ๋Œ์•„๊ฐ€๊ธฐ๋ฅผ ์‚ฌ์šฉ์ž๋Š” ์›ํ•˜์ง€ ์•Š์„ ๊ฒƒ์ด๋‹ค. 

๊ทธ๋Ÿผ ํ•ด๊ฒฐ๋ฐฉ์•ˆ์€? 
Navigation action์€ ๋‹ค์Œ destination์œผ๋กœ ์ด๋™ํ•˜๋ฉด์„œ back stack์„ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค. ๋”ฐ๋ผ์„œ GameOverFragment๋กœ ์ด๋™ํ•  ๋•Œ GameOverFragment๊ฐ€ back stack์— push ๋˜๊ธฐ ์ „์— GameFragment๋ฅผ back stack์—์„œ pop offํ•˜๋ฉด ํšจ์œจ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.
์•ˆ๋“œ๋กœ์ด๋“œ ์ŠคํŠœ๋””์˜ค ์—๋””ํ„ฐ ํ™”๋ฉด์˜ Pop Behaviour ํ•ญ๋ชฉ์—์„œ handleํ•  ์ˆ˜ ์žˆ๋‹ค. popTo GameFragment, Inclusive์— ์ฒดํฌํ•˜๋ฉด GameFragment๋ฅผ ํฌํ•จํ•˜์—ฌ(Inclusive) backstack์—์„œ pop off ํ•ด๋ฒ„๋ฆฐ๋‹ค. 

ํ•˜๋‚˜์˜ ์ผ€์ด์Šค๋ฅผ ๋” ๊ณ ๋ คํ•ด๋ณด์ž. 
GameOverFragment์—์„œ ๊ฒŒ์ž„ ๋‹ค์‹œ ์‹œ์ž‘ ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ ๋‹ค์‹œ Playํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด?
๊ฒŒ์ž„์ด ๋‹ค์‹œ ์‹œ์ž‘๋  ๋•Œ GameOverFragment๋Š” back stack์—์„œ ์ œ๊ฑฐํ•ด์•ผํ•  ๊ฒƒ์ด๋‹ค. popTo์—์„œ TitleFragment๋ฅผ ์„ ํƒํ•˜๊ณ  Inclusive๋Š” ์ฒดํฌํ•˜์ง€ ์•Š์œผ๋ฉด gameFragment๊ฐ€ ์ œ์ผ ์ƒ๋‹จ์— ์œ„์น˜ํ•˜๊ฒŒ ๋œ๋‹ค. 

์ด back stack handling์ด ์ ์šฉ๋œ action๋“ค์€ Kotlin ํŒŒ์ผ์—์„œ onClickListener์™€ ์—ฐ๊ฒฐํ•ด์ฃผ์–ด์•ผ ์ œ๋Œ€๋กœ ๋™์ž‘ํ•œ๋‹ค. 

13. Quiz: Back Stack Manipulation

14. Exercise: Adding Support for the Up Button

Action Bar์— up button ์ถ”๊ฐ€ํ•˜๊ธฐ. 
Navigation Controller๋Š” NavigatoinUI๋ผ๋Š” UI ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๊ฐ–๊ณ  ์žˆ๋‹ค. ์—ฌ๋Ÿฌ ๊ธฐ๋Šฅ ์ค‘์—์„œ action bar์™€ ํ†ตํ•ฉ๋˜์–ด up button์— ๋Œ€ํ•œ ์˜ฌ๋ฐ”๋ฅธ ๋™์ž‘์„ ๊ตฌํ˜„ํ•œ๋‹ค. 
NavigationUI๋Š” naviagtion controller์— access ํ•ด์•ผํ•œ๋‹ค. activity์—์„œ navigation controller๋ฅผ ์ฐพ๋Š” ๋ฐฉ๋ฒ•์€ NavHostFragment id๋ฅผ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋ฐ›๋Š” findNavController ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค. 

15. Android Navigation - Up vs Back

  • Up ๋ฒ„ํŠผ, Back ๋ฒ„ํŠผ ๋ชจ๋‘ ์•ฑ ๋‚ด์—์„œ ์ด๋™ํ•œ๋‹ค. 
  • Back ๋ฒ„ํŠผ์€ ์•ฑ์˜ ์™ธ๋ถ€, ๋‹ค๋ฅธ ์•ฑ์œผ๋กœ ์ด๋™์‹œํ‚จ๋‹ค. 

16. Google Interview: Ian Lake

https://www.youtube.com/watch?v=Enpgi-J4wWA 

17. Exercise: Adding a Menu

๋ฉ”๋‰ด๋Š” menu XML resource์—์„œ ์ƒ์„ฑํ•œ๋‹ค. 
๋ฉ”๋‰ด์˜ ์•„์ดํ…œ ID์™€ ๋ชฉ์ ์ง€ Fragment์˜ ID๋Š” ๋™์ผํ•˜๊ฒŒ ํ•˜์—ฌ ์–ด๋””๋กœ ์ด๋™ํ•˜๊ธฐ๋ฅผ ์›ํ•˜๋Š”์ง€ ๋„ค๋น„๊ฒŒ์ด์…˜์—์„œ ์•Œ๋ ค์ค€๋‹ค. 
ID๊ฐ€ ์„œ๋กœ ์ผ์น˜ํ•˜์ง€ ์•Š์œผ๋ฉด ์ด๋™ํ•˜์ง€ ์•Š๋Š”๋‹ค. 

๋ฉ”๋‰ด๋ฅผ ํ™”๋ฉด์—์„œ ๋ณด์—ฌ์ฃผ๋ ค๋ฉด?
MainActivity์— ๋‘๋ฉด ์•ฑ์˜ ๋ชจ๋“  ํ™”๋ฉด์—์„œ ๋ณด์—ฌ์ง„๋‹ค. 
๋จผ์ € ์•ˆ๋“œ๋กœ์ด๋“œ์—๊ฒŒ ๋ณด์—ฌ์ง€๊ธธ ์›ํ•˜๋Š” Activity / Fragment์— ์—ฐ๊ฒฐ๋œ ๋ฉ”๋‰ด๊ฐ€ ์žˆ์Œ์„ onCreate / onCreateView์—์„œ setHasOptionsMenu(true)๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ์•Œ๋ ค์ค€๋‹ค. 
Menu๋Š” onCreateOptionsMenu๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋“œํ•˜์—ฌ ์ƒ์„ฑํ•˜๋Š”๋ฐ layout์ฒ˜๋Ÿผ ๋ฉ”๋‰ด๋ฅผ inflateํ•œ๋‹ค. 
Menu Item์ด select๋˜๋ฉด onOptionsItemSelected ๋ฉ”์†Œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค. ํ•ด๋‹น ๋ฉ”๋‰ด์— ํ•ด๋‹นํ•˜๋Š” Fragment๋กœ ์ด๋™ํ•˜๋ ค๋ฉด NavigationUIํ•จ์ˆ˜์˜ ๋„์›€์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค. ๋งŒ์ผ NavigationUI๊ฐ€ ์„ ํƒ ํ•ญ๋ชฉ์— ๋Œ€ํ•ด handleํ•˜์ง€ ์•Š์œผ๋ฉด super.onOptionsItemSelected๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์•ฑ์ด navigation ์—†์ด menu item์„ ์ง์ ‘ handleํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•œ๋‹ค. 

์—ฌ๊ธฐ์„œ ์œ ์˜ํ•  ๋งŒํ•œ ์ ์€ menu๋Š” ์ด๋™ํ•˜๊ธฐ ์œ„ํ•œ action์„ ๋ณ„๋„๋กœ ์ƒ์„ฑํ•˜์ง€ ์•Š์•˜๋‹ค๋Š” ๊ฒƒ์ธ๋ฐ ๋ฉ”๋‰ด๋Š” ๋ณดํ†ต ํ•œ ๊ฐœ ์ด์ƒ์˜ destination์œผ๋กœ ๊ฐ€๊ธฐ ์œ„ํ•œ ๋ชฉ์ ์œผ๋กœ ์‚ฌ์šฉ๋œ๋‹ค. ๊ทธ๋ž˜์„œ ๊ฐ ๋ฉ”๋‰ด์— ๋Œ€ํ•œ action์„ ๋ช…์‹œํ•˜๊ธฐ๊ฐ€ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ menu์—์„œ๋Š” action์„ ์‚ฌ์šฉํ•˜๊ธฐ ๋ณด๋‹จ destination์œผ๋กœ ๋ฐ”๋กœ ์ด๋™ํ•œ๋‹ค. 

18. Quiz: Matching Menu Attributes

19. Exercise: Adding Safe Arguments

Fragments ๊ฐ„์— arguments ์ „๋‹ฌํ•˜๊ธฐ
Fragments๋Š” Android bundle ํ˜•ํƒœ ๋‚ด์— arguments๋ฅผ ํฌํ•จํ•œ๋‹ค. Key-Value์Œ์„ ์ €์žฅํ•˜๋Š”๋ฐ unique ํ‚ค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ associated value๋ฅผ fetch ํ•œ๋‹ค. bundle์—๋Š” ์ œํ•œ๋œ ํƒ€์ž…(๊ธฐ๋ณธ primitive type์ด๋‚˜ array ๊ฐ™์€ ๊ฐ’)์— ๋Œ€ํ•ด ๊ฐ’์œผ๋กœ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋‹ค. 

FragmentA โžก๏ธ Bundle โžก๏ธ FragmentB

val argBundle = Bundle() // FragmentA ํด๋ž˜์Šค์—์„œ argument bundle ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ
argBundle.putString(NAME_KEY_STRING, "content")
argBundle.puString(SERIAL_KEY_INT, 42)

val fragment = FramgmentB()
fragment.arguments = argBundle // FragmentB ์ธ์Šคํ„ด์Šค์— arguments๋ฅผ property๋กœ ์„ค์ •

ํ•˜์ง€๋งŒ ์ด ๋ฐฉ์‹์€ ๋ฒ„๊ทธ๊ฐ€ ์ƒ๊ธธ ์ˆ˜ ์žˆ๋‹ค. ํƒ€์ž…์ด ๋งž๋Š”์ง€ ๋ณด์žฅ์ด ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. 
๊ฐ’์„ ๋‹ด๋Š” ๋ณ€์ˆ˜์™€ arguments์˜ ํƒ€์ž…์ด ์ผ์น˜ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋‹ค. 

๊ทธ๋ž˜์„œ Navigation์€ Safe Args๋ผ๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค. 
Gradle plugin์œผ๋กœ ์–‘์ชฝ Fragment์—์„œ argument๊ฐ€ ์ผ์น˜ํ•˜๋Š” ์ฝ”๋“œ ์ž‘์„ฑ์„ ๋ณด์žฅํ•˜๋„๋ก ๋„์™€์ฃผ๊ณ  argument passing๋„ ๋‹จ์ˆœํ™” ์‹œ์ผœ์ค€๋‹ค. 
1๏ธโƒฃ build.gradle(project) ํŒŒ์ผ์— Safe Args Gradle plugin dependency๋ฅผ ์ถ”๊ฐ€ 
2๏ธโƒฃ build.gradle(App) ํŒŒ์ผ์˜ ์ƒ๋‹จ์— apply plugin: 'androidx.navigation.safeargs' ์ถ”๊ฐ€

Safe Arguments์™€ Nav direction์˜ ์ƒ๊ด€๊ด€๊ณ„? action ID๋ฅผ nav direction ํด๋ž˜์Šค์˜ action ์œผ๋กœ ๋ฐ”๊ฟ”์ฃผ์–ด arguments๋ฅผ ๋„˜๊ฒจ์ฃผ๊ธฐ ์œ„ํ•œ ์ค€๋น„๋ฅผ ํ•  ์ˆ˜ ์žˆ์Œ. (์ถ”๊ฐ€ ํ•„์š”)

Arguments๋Š” navigation.xml ์—๋””ํ„ฐ์—์„œ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค. 
๋„˜๊ฒจ๋ฐ›๊ธฐ ์›ํ•˜๋Š” Fragment์—์„œ arguments์˜ name๊ณผ type์„ ์ •ํ•ด์ค€๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ์œ„์—์„œ ๋ณ€๊ฒฝํ•ด์ค€ nav direction์—์„œ arguements๋ฅผ ๋„˜๊ฒจ์ค„ ์ˆ˜ ์žˆ๊ณ  ๋„˜๊ฒจ์ฃผ์ง€ ์•Š์œผ๋ฉด ์ปดํŒŒ์ผ๋˜์ง€ ์•Š๋Š”๋‹ค. 

20. Why do we have Safe Arguments?

21. Intents and Sharing

์•ˆ๋“œ๋กœ์ด๋“œ๋Š” ์•ฑ ๋‚ด์˜ activity ๊ฐ„์—๋„ ์ด๋™ํ•˜๋Š” ๊ฒƒ์„ ํ—ˆ์šฉํ•œ๋‹ค. ๋˜ ๋‹ค๋ฅธ ์•ฑ์—์„œ ์ œ๊ณตํ•˜๋Š” activity๋กœ๋„ ์ด๋™ํ•  ์ˆ˜ ์žˆ๋‹ค. (์นด๋ฉ”๋ผ, ์—ฐ๋ฝ์ฒ˜ ๋“ฑ)
Intent๋Š” ์•ฑ์˜ intention์„ ๋‚˜ํƒ€๋‚ธ๋‹ค. ์•ฑ์ด ๋ฌด์–ธ๊ฐ€ ํ•˜๊ธฐ ์›ํ•˜๋Š” activity. Intents๋Š” explicitํ•  ์ˆ˜๋„ implicitํ•  ์ˆ˜๋„ ์žˆ๋‹ค. 

Explicit intent is used to launch an activity using the name of the target activity class, and they are typically only used to launch other activities within your application, navigation component๊ฐ€ ์ด๊ฒƒ์„ ๋Œ€์‹ ํ•ด์ค€๋‹ค. navigation graph ๋‚ด์—์„œ ๋‹ค๋ฅธ activity๋กœ ์ด๋™ํ•˜๋„๋ก ๋„์™€์คŒ. 

Implicit intent๋Š” ์ˆ˜ํ–‰๋  ๋™์ž‘์— ๋Œ€ํ•œ ์ถ”์ƒ์ ์ธ description์„ ์ œ๊ณตํ•œ๋‹ค. ๋Œ€๊ฐœ ๋‹ค๋ฅธ ์•ฑ์— ์˜ํ•ด expose๋œ activity๋“ค์„ launchํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋œ๋‹ค. 

Explicit & Implicit Intent์— ๋Œ€ํ•œ ๋น„์œ 
- Explicit intent๋Š” ํŠน์ • local ํŽธ์˜์ ์— ๋Œ€ํ•œ ์„ค๋ช…. 
- Implicit intent๋Š” ๋ฐ˜๊ฒฝ 5๋งˆ์ผ ์ด๋‚ด์˜ ์œ ๊ธฐ๋† ์–‘๋ฐฐ์ถ”๋ฅผ ํŒŒ๋Š” ๊ฐ€๊ฒŒ๋“ค. ๋‚ด ๋ฐ˜๊ฒฝ 5๋งˆ์ผ ๋‚ด์— ์œ ๊ธฐ๋† ์–‘๋ฐฐ์ถ” ํŒŒ๋Š” ๊ฐ€๊ฒŒ๊ฐ€ ์—†์„ ์ˆ˜๋„ ์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ์‹œ์Šคํ…œ์—๋Š” implicit intent๋ฅผ handle ํ•  ์ˆ˜ ์žˆ๋Š” ์•ฑ์ด ์—†์„ ์ˆ˜๋„ ์žˆ๋‹ค. 

์—ฌ๋Ÿฌ ์•ฑ์ด ๋™์ผํ•œ implicit intent๋ฅผ handle ํ•  ์ˆ˜ ์žˆ์„ ๋•Œ ์•ˆ๋“œ๋กœ์ด๋“œ๋Š” compatible app ๋ชฉ๋ก์„ ๋ณด์—ฌ์ฃผ๊ณ  ๊ณ ๋ฅผ ์ˆ˜ ์žˆ๊ฒŒ ํ•œ๋‹ค. Implicit intent๊ฐ€ ์ค‘์š”ํ•œ ์ด์œ ๋Š” ๋‹ค๋ฅธ ์•ฑ์—์„œ ์•„๋ฌด๊ฒƒ๋„ ์•ฑ์— ๋Œ€ํ•ด ์•„๋Š” ๊ฒƒ ์—†์ด ๋ฌด์–ธ๊ฐ€๋ฅผ ์š”์ฒญํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๋งŒ์ผ ์‚ฌ์šฉ์ž๊ฐ€ text๋ฅผ ๊ณต์œ ํ•˜๊ธธ ์›ํ•œ๋‹ค๋ฉด ๋ฉ”์‹œ์ง€๋ฅผ ์‚ฌ์šฉํ• ์ง€ ์†Œ์…œ ๋„คํŠธ์›Œํฌ๋ฅผ ์‚ฌ์šฉํ• ์ง€๋Š” ์ค‘์š”ํ•˜์ง€ ์•Š๋‹ค. ์ด ์š”์ฒญํ•˜๋Š” ๊ฒƒ์„ handleํ•  ์ˆ˜ ์žˆ๋Š” activity๋ฅผ ๊ฐ€์ง„ ์•ฑ์ด๋ฉด ๋œ๋‹ค. 

๊ฐ implicit intent๋Š” action์ด ๋ฐ˜๋“œ์‹œ ํ•„์š”ํ•˜๋‹ค. ์—ฌ๊ธฐ์„œ์˜ action์€ navigation action๊ณผ๋Š” ์™„์ „ํžˆ ๋‹ค๋ฅด๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” the type of thing that the app wants to have done on its behalf. Common actions๋Š” intent class์— ์ •์˜๋˜์–ด ์žˆ๋‹ค. 
Implicit intent๋Š” operation์„ ๋ฌ˜์‚ฌํ•˜๊ธฐ ์œ„ํ•œ ์นดํ…Œ๊ณ ๋ฆฌ์™€ ๋ฐ์ดํ„ฐ ํƒ€์ž…์ด ์žˆ๋‹ค. ์นดํ…Œ๊ณ ๋ฆฌ๋Š” ํ•ญ์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š๊ณ  action์˜ ์• ๋งคํ•จ์„ ์—†์• ๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋œ๋‹ค. ๋ฐ์ดํ„ฐ ํƒ€์ž…์€ text, jpeg์™€ ๊ฐ™์ด ๋ฐ์ดํ„ฐ ํƒ€์ž…์„ ํฌํ•จํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๊ฒƒ์€ accept ๊ฐ€๋Šฅํ•œ ๋ฐ์ดํ„ฐ ํƒ€์ž…์— ๋”ฐ๋ผ ์•ฑ์ด ์„ ํƒ๋˜๋„๋กํ•œ๋‹ค. 

๋ชจ๋“  activity๋Š” launch๋˜๋ ค๋ฉด AndroidManifest.xml์— ๋“ฑ๋ก๋˜์–ด ์žˆ์–ด์•ผ ํ•œ๋‹ค. 
Explicity launch๋˜๋Š” activity์˜ ๊ฒฝ์šฐ <activity> ํƒœ๊ทธ๋กœ๋งŒ ์„ ์–ธ๋œ๋‹ค. 
Implicitly launch๋˜๋Š” activity์˜ ๊ฒฝ์šฐ <intent-filter> ํƒœ๊ทธ๊ฐ€ ํ•„์š”ํ•˜๋‹ค. 
์ด intent-filter๋Š” activity๋ฅผ ํŠน์ • action, category, type์˜ implicit intent์— ์‘๋‹ตํ•  ์ˆ˜ ์žˆ์Œ์„ ๋…ธ์ถœ์‹œํ‚ค๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋œ๋‹ค. 

22. Quiz: Explicit vs Implicit Intents

24. Exercise: Adding the Navigation Drawer

Navigation drawer: ์Šคํฌ๋ฆฐ์˜ ๊ฒฝ๊ณ„๋ฉด์—์„œ ์Šฌ๋ผ์ด๋“œ ๋˜์–ด ๋‚˜์˜ค๋Š” panel. ๋ณดํ†ต ํ—ค๋”์™€ ๋ฉ”๋‰ด๊ฐ€ ์žˆ๋‹ค. ์ขŒ์ธก ์Šคํฌ๋ฆฐ ๊ฒฝ๊ณ„์—์„œ ์Šฌ๋ผ์ด๋“œํ•˜๊ฑฐ๋‚˜, action bar์˜ ํ–„๋ฒ„๊ฑฐ ๋ฉ”๋‰ด๋ฅผ ๋ˆ„๋ฅด๋ฉด ๋‚˜์˜ค๋Š” ๋ฉ”๋‰ด์ด๋‹ค. ๋Œ€๊ฐœ 5๊ฐœ๋‚˜ ๊ทธ ์ด์ƒ์˜ primary destination์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๋ณต์žกํ•œ ์•ฑ์—์„œ ์‚ฌ์šฉํ•œ๋‹ค. primary destination์ด๋ž€ navigation hierarchy์—์„œ ๋™์ผ ์œ„์น˜๋ฅผ ๊ฐ–๋Š” ๊ฒฝ์šฐ์ธ๋ฐ ๊ฐ™์€ navigation parent, start destination์„ ๊ฐ–๋Š”๋‹ค. 

Navigation drawer์—์„œ destination ๊ฐ„์— ์ด๋™ํ•  ๋•Œ it pops the back stack back to the start destinatoin, and then pushes the destinaton to be navigated to as the second element on the stack. (๋‚ด ํ•ด์„์— ๋”ฐ๋ฅด๋ฉด navigaton drawer์˜ destination๋“ค์€ ๊ฐ™์€ depth๋ฅผ ๊ฐ–๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— navigatoin drawer์˜ A ๋ฉ”๋‰ด์— ๋“ค์–ด๊ฐ”๋‹ค๊ฐ€ B ๋ฉ”๋‰ด์— ๋“ค์–ด๊ฐ€๋ฉด back stack A ์œ„์— B๊ฐ€ ์Œ“์ด๋Š” ๊ฒƒ์ด ์•„๋‹Œ A๊ฐ€ pop out ๋˜๊ณ  B๊ฐ€ ๋“ค์–ด๊ฐ. )

Navigation drawer๋Š” material library์˜ ์ผ๋ถ€์ด๋‹ค. 

26. Quiz: How to Navigate

27. Exercise: Using Navigation Listeners

 Navigation Listener๋Š” ์šฐ๋ฆฌ๊ฐ€ navigate ํ•  ๋•Œ ๋งˆ๋‹ค ํ˜ธ์ถœ๋˜๋Š” single method interface์ด๋‹ค. Naviagate ํ•˜๋Š” ๋™์•ˆ ๋ฌด์–ธ๊ฐ€๋ฅผ ํ•˜๊ฑฐ๋‚˜, ๋ง‰๋Š” ์ผ์„ ํ•  ์ˆ˜ ์žˆ๋‹ค. 

28. Animation with Navigation

Navigation์—์„œ animation์„ ์‚ฌ์šฉํ•˜๋ฉด ์—ฌ๋Ÿฌ ์•ฑ๋“ค ์ค‘ ๋ˆˆ์— ๋„๊ฒŒ ํ•ด์ฃผ๊ธฐ๋„ ํ•˜์ง€๋งŒ ์‚ฌ์šฉ์ž๊ฐ€ ์•ฑ์˜ ํ๋ฆ„์„ ์ด์• ํ•˜๋Š”๋ฐ์—๋„ ๋„์›€์„ ์ค€๋‹ค. ์ด๋Ÿฐ transition์€ XML animation resources์— ์˜ํ•ด์„œ control ๋œ๋‹ค. 
res > anim > xml ํŒŒ์ผ ์ƒ์„ฑํ•˜์—ฌ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š”๋ฐ <set></set> ๋‚ด๋ถ€์— ๋ช…๋ น์–ด๋“ค์„ ํ†ตํ•ด ๊ฐ™์ด ๋™์ž‘ํ•˜๊ฑฐ๋‚˜ ์ˆœ์„œ๋Œ€๋กœ ๋™์ž‘ํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋˜ set ์•ˆ์— set์„ ๋‘˜ ์ˆ˜๋„ ์žˆ๋‹ค. 

Alpha๋Š” ์–ด๋–ค ๊ฒƒ์ด ์–ผ๋งˆ๋‚˜ ํˆฌ๋ช…ํ•œ๊ฐ€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š”๋ฐ 0%๋Š” ๋ณด์ด์ง€ ์•Š์Œ, 100%๋Š” ๋ถˆํˆฌ๋ช…ํ•œ ๊ฒƒ์„ ๋‚˜ํƒ€๋‚ธ๋‹ค. 

X offset์— ๋Œ€ํ•˜์—ฌ -100%๋Š” ์Šคํฌ๋ฆฐ ์ขŒ์ธก, 100%๋Š” ์Šคํฌ๋ฆฐ ์šฐ์ธก. 
Y offset์— ๋Œ€ํ•˜์—ฌ -100%๋Š” ์Šคํฌ๋ฆฐ ์ƒ๋‹จ, 100%๋Š” ์Šคํฌ๋ฆฐ ํ•˜๋‹จ. 

29. Quiz: Animation Attributes

'Android & Kotlin' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

Lesson 5: App Architecture(UI Layer)  (0) 2022.02.22
๊ณต๋ถ€ ์ฃผ์ œ  (0) 2022.02.19
Lesson 4: Activity & Fragment Lifecycle  (0) 2022.02.11
Lesson 2: Layouts  (0) 2022.02.06
Lesson 1: Build your First App  (0) 2022.02.06