돌아오신 것을 환영합니다
지난 강의에서는 화면을 설정했고 sealed 클래스와 객체 등도
설정했습니다
처음에는 다소 헷갈릴 수 있지만 어떻게 사용하는 지를 알아볼 것이며
나중에 발생할 두통이 많이 줄어들 것입니다
그저 한번 더 말씀드리고 싶었습니다
이제 기본적으로 앱을 관리할 앱을 만들겠습니다
지금까지는 MainActivity가 앱을 관리했는데
MainActivity는 시작 지점이어야 하며
앱을 직접 실행한 후에 화면을 실행해야 합니다
그러므로 이 전에 우리가 봤던 것처럼 기본적으로 앱이 탐색을 관리해야 합니다
새 파일을 만드는데 RecipeApp이라고 하겠습니다
그리고
이렇게 하겠습니다
좋습니다
RecipeApp은 컴포저블이며
이 컴포저블은 RecipeApp이라고 하겠습니다
NavController자료형의 navController가 필요합니다
그리고 안에서 MainViewModel자료형의
recipeViewModel을 만들고
기본 값은 viewModel로 하겠습니다
좋습니다
initializer없이 기본 viewModel입니다
그리고 상태가 필요합니다
viewstate인데
by recipeViewModel.categoriesState라고 하겠습니다
좋습니다
import하겠습니다
이 categoriesState는 무엇입니까
꽤 이전에 만든 MainViewModel을 보면
이 categoriesState를 관리하고 있는데 RecipeState자료형의 State입니다
이는 모든 레시피의 list를 관리하는데
우리의 경우에는 레시피 카테고리의 list입니다
이제 무엇을 전달할 지 알기 위해서 이를 사용하려 합니다
예를 들어 사용자가 어떤 것을 클릭해서 다른 화면으로 이동하는지 말입니다
RecipeApp에 그 정보가 필요하므로
그 viewstate를 이용해서 다른 화면으로의 이동 뿐만 아니라 RecipeScreen을
보여줄 것입니다
이제 NavHost를 설정하는데 navController가 필요합니다
그래서 navController를 여기서 전달받았습니다
그리고 시작 지점도 필요한데
이 graph를 지우고 startDestination이라고 하겠습니다
이제 시작 지점을 전달해야 하는데 Screen.RecipeScreen.route입니다
이 것은 무엇일까요
이 Screen을 route 속성 때문에 사용했는데 이 전역 정적 변수는
변하지 않아 오류가 발생할 일 없이 접근할 수 있습니다
기본적으로 여기에 그냥 원하는 경로를 입력할 수도
있지만
예를 들어 recipescreen과 같이 말입니다
그렇게 하는 대신에 이 것을 사용했습니다
오류를 피하기 위해 말입니다
이제 이 NavHost는 실행할 코드도 필요합니다
그런데 RecipeApp이 NavController가 아니라 NavHostController가 필요한 것이라는 사실을 깨달았습니다
그러므로 NavHostController로 바꿉니다
그 것이 이 NavHost가 필요한 것이기 때문입니다
NavHostController자료형이 필요하며 이 NavController는 지울 수 있습니다
이 NavHostController는 두개의 다른 컴포저블을 관리할 수 있습니다
레시피 화면을 위한 컴포저블과 상세 화면을 위한 컴포저블이 있는데
route를 여기 위에서 사용했던 것과 동일한 것을 사용하면 됩니다
그러므로 Screen.RecipeScreen.route입니다
오타를 내거나 하지 않도록 확실하게 하기 위한 우리의 방법일 뿐입니다
이제 경로를 지정했으니 여기에 어떤 컴포저블이 보여야 할 지 정할 수 있습니다
우리의 경우에는 레시피 화면입니다
RecipeScreen은 navigateToDetail이 필요하며 상태도 필요하게
만들겠습니다
여기를 보면
navigateToDetail이 필요한데
viewstate도 필요할 것입니다
여기서 만드는 대신에 RecipeApp에서
전달하도록 하겠습니다
여기서 지우고
여기서 설정하는데 viewstate이고 MainViewModel
.RecipeState자료형 입니다
좋습니다
이제 RecipeScreen은 viewstate도 필요합니다
그리고 이는 여기서 사용한 viewstate와 동일합니다
보시는 것처럼 아무 것도 바뀌지 않았습니다
뷰 모델을 여기서 설정할 필요가 없습니다
RecipeApp에서 관리할 것이기 떄문에
화면에서 관리하면 안됩니다
앱에서 관리해야 합니다
여기에 viewstate가 있으니
이제 viewstate도 navigateToDetail과 같이 전달할 수 있습니다
이제 여기서 navigateToDetail코드를 이렇게 구현하겠습니다
viewstate도 필요하므로
viewstate도 전달합니다
viewstate = viewstate입니다
이 것 말입니다
이 것이 RecipeScreen이 필요한 것입니다 왜냐하면 여기서 그렇게 설정했기 때문입니다
viewstate가 필요하게 설정했으므로
이제 viewstate를 전달 받습니다
이제 navigateToDetail이 할 일을 구현해야 하는데
이는 여기에서 필요한 navigateToDetail이기 때문입니다
카테고리가 필요하고
어떤 코드가 실행될 것입니다
혹은 무엇이 실행될 지를 구현해야 합니다
이제 실행되어야 할 것은
사실 한 화면에서 다른 화면으로 이동하는 것입니다
category도 전달 받았습니다
it: Category라고 보입니다
이 카테고리가 필요한데 잘 전달 받았습니다
여기서 할 것은 조금 더 복잡한데
navController.currentBackStackEntry.savedStateHandle.set이며
null이 될 수 있으므로
물음표를 설정했습니다
그리고 cat이라고 부르고
it을 전달합니다
좋습니다
이제 이 navController를 이용해서 탐색합니다
어떤 화면이나 경로로 이동할지 지정해야 합니다
Screen.DetailScreen.route로 이동합니다
좋습니다
많은 일이 일어났으므로 무슨 일이 일어났는지 살펴봅시다
여기에 먼저 붙여 넣겠습니다
무슨 일이 일어났는 지에 대해 아주 좋은 설명이 있는데
이 것은 주석처리합니다
이 부분이 현재 화면에서 상세 화면으로 데이터를 전달하는 역할을 합니다
이 부분으로 currentBackStackEntry를 얻는데 이는 탐색 그래프의
현재 화면의 상태를 나타내며
탐색을 얻습니다
기본적으로 시작 지점이 있고
화면이 있는데 레시피 화면이라고 합니다
그리고 상세 화면으로 가서
상세 화면에서도 클릭해서 다른 화면으로 가는
이 모든 흐름이 이 BackStackEntry에 저장되어 있습니다
이 savedStateHandle이 Jetpack Compose 탐색을 이용해서 다른 화면 간에 데이터를 전달하는
메커니즘입니다
다음 화면으로 전달되어야 하는 데이터를 저장하고 되찾는 방법을 제공합니다
다음으로 이 set("cat", it)이 있는데
이 메소드는 savedStateHandle에 키-값 쌍을 저장합니다
이 키-값 쌍의 키는 cat이고 값은 it입니다
그러므로 여기서 우리가 얻는 것은 카테고리입니다
기억해보시면 RecipeScreen에서 얻는 것도 category입니다
그러므로 이 것을 navigateToDetail에 전달합니다
그리고 키는 상세 화면에서 데이터를 되찾기 위한 참조로 사용됩니다
기본적으로 이 것은 여기에 카테고리를 저장한다는 의미이며
상세 화면에서 이 정보를 되찾아야 합니다
그리고 여기에서 상세 화면으로 탐색을 시작합니다
그리고 navController를 이용해 Screen에 있는 Screen.DetailScreen.route가 나타내는
화면으로 이동합니다
이 것입니다
이 detailscreen경로를 가지고 말입니다
이제 상세 화면을 설정할 수 있습니다
이제 여기서 다른 컴포저블을 만들 것인데 여기가 아니라 밖에서 합니다
올바른 지점인지 확인합니다
여기서 컴포저블을 사용하는데
경로를 Screen.Recipes롤
아니 DetailScreen.route로 설정해서
detailscreen을 얻는데
이 것이 경로입니다
그리고 우리는
AnimatedContentScope와 NavBackStackEntry를 전달 받는데
이 BackStackEntry를 이용해서 카테고리를 되찾을 것입니다
val category = navController.previousBackStackEntry인데
currentBackStackEntry와 동일한 것으로 이 또한 null이 가능합니다
그리고 savedStateHandle을 얻는데 이 또한 null이 가능하고
이제 키를 얻습니다
우리가 얻을 키의 자료형은 Category입니다
값이 Category자료형일 것입니다
그러므로 Category자료형으로 get하는데
키를 전달하는데 키는 cat입니다
만약 null이라면 Category를 만드는데
idCategory와 strCategory와
썸네일과 설명이 빈 Category입니다
이 줄은 무엇일까요
줄을 나눠서 좀 더 읽기 쉽게 하겠습니다
기본적으로 의미하는 것은, get은 여기 있어야 하고
이렇게 말입니다
이 것은 한 줄입니다
여전히 한 줄 입니다
category를 얻고 싶은데 이는 savedStateHandle에 들어 있고 이는 이 것입니다
여기에 저장했는데
currentBackStack이었지만
클릭해서 다음 화면으로 가면
previousBackStackEntry를 얻어야 합니다
기본적으로 우리가 다른 화면으로 이동했으므로 백 스택에 다른 컴포넌트가 있는데
이전의 백 스택을 얻고 싶은데 이는 previousBackStackEntry가 됩니다
거기에서 이 savedStateHandle을 얻는데 변수들을 저장할 수 있는 컨테이너 같은
것입니다
cat이라는 키로 제가 얻는 카테고리를 저장합니다
이제 그 카테고리를 되찾는데 되찾는 것의 자료형은
Category이고 그 것의 위치인
키는 cat입니다
이는 기본적으로 it이며 category에 저장됩니다
그리고 이는 우리가 RecipeScreen으로 전달한 무엇 인가가 되고 레시피
화면을 만들 때 category를 전달합니다
그리고
만약 cat이 비었다면
빈 Category를 만드는 데 id도 스트링도 이미지도 설명도 없습니다
좋습니다
이 것이 여기에서 하는 일입니다
이제 이 category를 실제로 CategoryDetailScreen으로 전달해야 합니다
해보겠습니다
이 것이 CategoryDetailScreen파일인 실제 컴포저블입니다
이 것 말입니다
상세 화면에 보여주기 위해 category가 필요합니다
많은 일들이 벌어지고 있는데
이제 두 가지만 더 하면
이 탐색은 끝입니다
MainActivity대신에 RecipeApp으로 갈 것인데 RecipeScreen이 아니라
RecipeApp입니다 navController가 필요하므로 setContent안에서 navController를
만들겠습니다
val navController는
rememberNavController자료형으로 navController를 설정했고 이제 이 navController를 RecipeApp으로
전달합니다
기억해 보시면 RecipeApp은 navController만 필요합니다
이제 여기서 탐색을 관리할 수 있습니다
이제 한 가지만 남았습니다
말씀 드렸던 것처럼 직렬화와 역직렬화 입니다
이번 강의에서 구현하고 테스트 할 것이지만 다음 강의에서 설명하겠습니다
여기 이 Build.gradle Module파일에 application이 있고 jetpack kotlin android가
있습니다
여기에 다른 플러그인을 추가하는데 kotlin-parcelize이며
큰 따옴표 안에 있어야 합니다
이제 동기화 하겠습니다
동기화 했으므로
이제 객체를 꾸러미화 할 수 있습니다
다음 강의에서 무슨 뜻인지 알아보겠지만
지금은 category가 꾸러미화
되도록 하겠습니다 @Parcelize입니다
이렇게 입력하고
이 것입니다
그리고 이것을 Parcelable해야 합니다
이렇게 Parcelable라고 말입니다
이제 앱을 실행합니다
말씀 드렸듯이 다음 강의에서 깊게 설명하겠습니다
이번 강의는 이미 충분히 깁니다
앱이 실행됐습니다
Beef로 가보면
소고기에 대한 상세 화면이 나타납니다
이제 뒤로 스와이프해서 chicken입니다
chicken 상세 화면이 나타납니다
다시 뒤로 스와이프해서
엄청 긴 설명이 pork였던 것 같습니다
맞습니다
보시는 것처럼 실제로 텍스트를 스크롤 해서 볼 수 있습니다
좋습니다
애플리케이션이 잘 작동합니다
탐색에 관련된 작업이 굉장히 많았습니다
하지만 다음 강의에서 마지막 한 가지를 살펴볼텐데
방금 구현하고 설명하지 않은 parcelize(꾸러미화)라는 개념입니다
다음 강의에서 설명 드리겠습니다