Slide 1

Slide 1 text

This work is licensed under the Apache 2.0 License Unit 4. Navigation and App Architecture Jaesung Lee GDSC HUFS #android

Slide 2

Slide 2 text

This work is licensed under the Apache 2.0 License

Slide 3

Slide 3 text

This work is licensed under the Apache 2.0 License Jaesung Lee GDSC HUFS 캠핑지기 @jdoongxx JaesungLeee

Slide 4

Slide 4 text

This work is licensed under the Apache 2.0 License 캠핑지기

Slide 5

Slide 5 text

This work is licensed under the Apache 2.0 License TOPIC - Unit 4 PATHWAY 1: Architecture Components PATHWAY 2: Navigation in Jetpack Compose PATHWAY 3: Adapt for different screen sizes Today’s Schedule

Slide 6

Slide 6 text

PATHWAY 1 Architecture Components

Slide 7

Slide 7 text

This work is licensed under the Apache 2.0 License Lifecycle

Slide 8

Slide 8 text

This work is licensed under the Apache 2.0 License Activity Lifecycle // MainActivity.kt override fun onCreate() { super.onCreate() } override fun onStart() { super.onStart() } override fun onResume() { super.onResume() } override fun onRestart() { super.onRestart() } override fun onPause() { super.onPause() } override fun onStop() { super.onStop() } override fun onDestroy() { super.onDestroy() }

Slide 9

Slide 9 text

This work is licensed under the Apache 2.0 License Activity Lifecycle // MainActivity.kt override fun onCreate() { super.onCreate() } override fun onStart() { super.onStart() } override fun onResume() { super.onResume() } override fun onRestart() { super.onRestart() } override fun onPause() { super.onPause() } override fun onStop() { super.onStop() } override fun onDestroy() { super.onDestroy() } Called once during the Activity Lifecycle

Slide 10

Slide 10 text

This work is licensed under the Apache 2.0 License Case 1: Open, Close In Activity // MainActivity.kt override fun onCreate() { super.onCreate() } override fun onStart() { super.onStart() } override fun onResume() { super.onResume() } override fun onRestart() { super.onRestart() } override fun onPause() { super.onPause() } override fun onStop() { super.onStop() } override fun onDestroy() { super.onDestroy() }

Slide 11

Slide 11 text

This work is licensed under the Apache 2.0 License Case 1: Open, Close In Activity // MainActivity.kt override fun onCreate() { super.onCreate() } override fun onStart() { super.onStart() } override fun onResume() { super.onResume() } override fun onRestart() { super.onRestart() } override fun onPause() { super.onPause() } override fun onStop() { super.onStop() } override fun onDestroy() { super.onDestroy() }

Slide 12

Slide 12 text

This work is licensed under the Apache 2.0 License Case 2: Navigate back to Activity // MainActivity.kt override fun onCreate() { super.onCreate() } override fun onStart() { super.onStart() } override fun onResume() { super.onResume() } override fun onRestart() { super.onRestart() } override fun onPause() { super.onPause() } override fun onStop() { super.onStop() } override fun onDestroy() { super.onDestroy() }

Slide 13

Slide 13 text

This work is licensed under the Apache 2.0 License Case 2: Navigate back to Activity // MainActivity.kt override fun onCreate() { super.onCreate() } override fun onStart() { super.onStart() } override fun onResume() { super.onResume() } override fun onRestart() { super.onRestart() } override fun onPause() { super.onPause() } override fun onStop() { super.onStop() } override fun onDestroy() { super.onDestroy() }

Slide 14

Slide 14 text

This work is licensed under the Apache 2.0 License Case 3: Partially hide the Activity // MainActivity.kt override fun onCreate() { super.onCreate() } override fun onStart() { super.onStart() } override fun onResume() { super.onResume() } override fun onRestart() { super.onRestart() } override fun onPause() { super.onPause() } override fun onStop() { super.onStop() } override fun onDestroy() { super.onDestroy() }

Slide 15

Slide 15 text

This work is licensed under the Apache 2.0 License Case 3: Partially hide the Activity // MainActivity.kt override fun onCreate() { super.onCreate() } override fun onStart() { super.onStart() } override fun onResume() { super.onResume() } override fun onRestart() { super.onRestart() } override fun onPause() { super.onPause() } override fun onStop() { super.onStop() } override fun onDestroy() { super.onDestroy() }

Slide 16

Slide 16 text

This work is licensed under the Apache 2.0 License // MainActivity.kt ... override fun onDestroy() { super.onDestroy() } 1. Activity#finish 2. Configuration Changes in Compose: rememberSaveable

Slide 17

Slide 17 text

This work is licensed under the Apache 2.0 License ● Separation of Concerns (관심사 분리) ● Drive UI from a model (Data 모델에서 UI 도출하기) Android App Architecture

Slide 18

Slide 18 text

This work is licensed under the Apache 2.0 License ● UI elements (Jetpack Compose) ● State Holder (ViewModel) UI Layer

Slide 19

Slide 19 text

This work is licensed under the Apache 2.0 License ● Unidirectional Data Flow UDF Pattern

Slide 20

Slide 20 text

This work is licensed under the Apache 2.0 License // GameViewModel.kt private val _uiState = MutableStateFlow(GameUiState()) val uiState: StateFlow = _uiState.asStateFlow() _uiState.value = GameUiState( currentScrambledWord = pickRandomWordAndShuffle() ) // GameScreen.kt @Composable fun GameScreen( modifier: Modifier = Modifier, gameViewModel: GameViewModel = viewModel() ) { val gameUiState by gameViewModel.uiState.collectAsState() // ... } UI State with StateFlow

Slide 21

Slide 21 text

This work is licensed under the Apache 2.0 License // GameViewModel.kt private val _uiState = MutableStateFlow(GameUiState()) val uiState: StateFlow = _uiState.asStateFlow() _uiState.value = GameUiState( currentScrambledWord = pickRandomWordAndShuffle() ) // GameScreen.kt @Composable fun GameScreen( modifier: Modifier = Modifier, gameViewModel: GameViewModel = viewModel() ) { val gameUiState by gameViewModel.uiState.collectAsState() // ... } UI State with StateFlow

Slide 22

Slide 22 text

This work is licensed under the Apache 2.0 License // GameViewModel.kt private val _uiState = MutableStateFlow(GameUiState()) val uiState: StateFlow = _uiState.asStateFlow() _uiState.value = GameUiState( currentScrambledWord = pickRandomWordAndShuffle() ) // GameScreen.kt @Composable fun GameScreen( modifier: Modifier = Modifier, gameViewModel: GameViewModel = viewModel() ) { val gameUiState by gameViewModel.uiState.collectAsState() // ... } UI State with StateFlow

Slide 23

Slide 23 text

This work is licensed under the Apache 2.0 License ● Dessert Clicker app ● Unscramble app PATHWAY 1 Codelabs

Slide 24

Slide 24 text

PATHWAY 2 Navigation in Jetpack Compose

Slide 25

Slide 25 text

This work is licensed under the Apache 2.0 License Compose Navigation 2 3 4 1 Destinations NavHost NavController Route

Slide 26

Slide 26 text

This work is licensed under the Apache 2.0 License Destinations

Slide 27

Slide 27 text

This work is licensed under the Apache 2.0 License ● navController ● startDestination NavHost

Slide 28

Slide 28 text

This work is licensed under the Apache 2.0 License NavController // CupcakeScreen.kt @Composable fun CupcakeApp( modifier: Modifier = Modifier, viewModel: OrderViewModel = viewModel(), navController: NavHostController = rememberNavController() ) { Scaffold( ... ) { innerPadding -> ... NavHost( navController = navController, startDestination = CupcakeScreen.Start.name, modifier = modifier.padding(innerPadding) ) { composable(route = CupcakeScreen.Start.name) { ... } } } } ● rememberNavController()

Slide 29

Slide 29 text

This work is licensed under the Apache 2.0 License // CupcakeScreen.kt NavHost( navController = navController, startDestination = CupcakeScreen.Start.name, modifier = modifier.padding(innerPadding) ) { composable(route = CupcakeScreen.Start.name) { StartOrderScreen( quantityOptions = quantityOptions, onNextButtonClicked = { ... navController.navigate( CupcakeScreen.Flavor.name ) } ) } ... } Routes

Slide 30

Slide 30 text

This work is licensed under the Apache 2.0 License ● Back button, Up button Back Stack

Slide 31

Slide 31 text

This work is licensed under the Apache 2.0 License ● Cupcake app ● Lunch Tray Practice PATHWAY 2 Codelabs

Slide 32

Slide 32 text

PATHWAY 3 Adapt for different screen sizes

Slide 33

Slide 33 text

This work is licensed under the Apache 2.0 License Adaptive Layout

Slide 34

Slide 34 text

This work is licensed under the Apache 2.0 License Material Design Breakpoint Range https://m3.material.io/foundations/adaptive-design/large-screens/overview

Slide 35

Slide 35 text

This work is licensed under the Apache 2.0 License WindowSizeClass API // MainActivity.kt setContent { ReplyTheme { val windowSize = calculateWindowSizeClass(this) ReplyApp( windowSize = windowSize.widthSizeClass ) } }

Slide 36

Slide 36 text

This work is licensed under the Apache 2.0 License WindowSizeClass API // ReplyApp.kt @Composable fun ReplyApp( windowSize: WindowWidthSizeClass, ... ) { ... when (windowSize) { WindowWidthSizeClass.Compact -> { ... } WindowWidthSizeClass.Medium -> { ... } WindowWidthSizeClass.Expanded -> { ... } else -> { ... } } }

Slide 37

Slide 37 text

This work is licensed under the Apache 2.0 License ● https://github.com/gdgand/ComposeCamp202 2-for-Beginners PATHWAY 3 Codelabs

Slide 38

Slide 38 text

This work is licensed under the Apache 2.0 License Unit 4 코드랩을 시작해주세요. https://developer.android.com/courses/android-basics-co mpose/unit-4 Compose Camp 비기너 코스 최종 수료를 위한 PR 작성도 잊지 마세요!!