이 Codelab은 Android Kotlin 기초 과정의 일부입니다. Codelab을 순서대로 진행하면 이 과정의 학습 효과를 극대화할 수 있습니다. 모든 과정 Codelab은 Android Kotlin 기본사항 Codelab 방문 페이지에 나열되어 있습니다.
소개
이 Codelab에서는 ViewModel
와 프래그먼트를 함께 사용하여 탐색을 구현하는 방법을 간략하게 설명합니다. 탐색할 시기의 로직은 ViewModel
에 넣고 경로는 프래그먼트와 탐색 파일에 정의하는 것이 목표입니다. 이 목표를 달성하려면 뷰 모델, 프래그먼트, LiveData
, 관찰자를 사용합니다.
이 Codelab에서는 코드를 최소화하여 버튼 상태를 추적하는 방법을 보여주며, 이를 통해 사용자가 버튼을 탭하는 것이 적절한 경우에만 각 버튼이 사용 설정되고 클릭 가능하도록 합니다.
기본 요건
다음을 잘 알고 있어야 합니다.
- 활동, 프래그먼트, 뷰를 사용하여 기본 사용자 인터페이스 (UI)를 빌드합니다.
- 프래그먼트 간 탐색 및
safeArgs
을 사용하여 프래그먼트 간 데이터 전달 - 모델, 모델 팩토리, 변환,
LiveData
및 관찰자를 확인합니다. Room
데이터베이스를 만들고, 데이터 액세스 객체 (DAO)를 만들고, 항목을 정의하는 방법- 데이터베이스 상호작용 및 기타 장기 실행 작업에 코루틴을 사용하는 방법
학습할 내용
- 데이터베이스에서 기존 수면의 질 기록을 업데이트하는 방법
LiveData
를 사용하여 버튼 상태를 추적하는 방법- 이벤트에 대한 응답으로 스낵바를 표시하는 방법
실습할 내용
- TrackMySleepQuality 앱을 확장하여 품질 평점을 수집하고 데이터베이스에 평점을 추가한 후 결과를 표시합니다.
LiveData
를 사용하여 스낵바 표시를 트리거합니다.LiveData
를 사용하여 버튼을 사용 설정 및 중지합니다.
이 Codelab에서는 TrackMySleepQuality 앱의 수면의 질 기록 및 최종 UI를 빌드합니다.
앱에는 프래그먼트로 표현되는 두 개의 화면이 있습니다(아래 그림 참고).
왼쪽에 표시된 첫 번째 화면에는 추적을 시작하고 중지하는 버튼이 있습니다. 화면에는 사용자의 모든 수면 데이터가 표시됩니다. 지우기 버튼은 앱이 사용자를 위해 수집한 모든 데이터를 완전히 삭제합니다.
오른쪽에 표시된 두 번째 화면은 수면의 질 평가를 선택하는 화면입니다. 앱에서 평점은 숫자로 표시됩니다. 개발 목적으로 앱은 얼굴 아이콘과 숫자 값을 모두 표시합니다.
사용자의 흐름은 다음과 같습니다.
- 사용자가 앱을 열면 수면 추적 화면이 표시됩니다.
- 사용자가 시작 버튼을 탭합니다. 시작 시간을 기록하고 표시합니다. 시작 버튼은 사용 중지되고 중지 버튼은 사용 설정됩니다.
- 사용자가 중지 버튼을 탭합니다. 이렇게 하면 종료 시간이 기록되고 수면의 질 화면이 열립니다.
- 사용자가 수면의 질 아이콘을 선택합니다. 화면이 닫히고 추적 화면에 수면 종료 시간과 수면의 질이 표시됩니다. 중지 버튼은 사용 중지되고 시작 버튼은 사용 설정됩니다. 앱이 또 다른 밤을 맞이할 준비가 되었습니다.
- 데이터베이스에 데이터가 있으면 언제든지 지우기 버튼이 사용 설정됩니다. 사용자가 지우기 버튼을 탭하면 모든 데이터가 복구할 수 없이 삭제됩니다. '정말로 지우시겠습니까?' 메시지가 표시되지 않습니다.
이 앱은 전체 아키텍처의 컨텍스트에서 아래와 같이 간소화된 아키텍처를 사용합니다. 앱은 다음 구성요소만 사용합니다.
- UI 컨트롤러
- 모델 및
LiveData
보기 - Room 데이터베이스
이 Codelab에서는 프래그먼트와 탐색 파일을 사용하여 탐색을 구현하는 방법을 알고 있다고 가정합니다. 작업을 저장할 수 있도록 이 코드의 상당 부분이 제공됩니다.
1단계: 코드 검사
- 시작하려면 이전 Codelab의 끝부분에서 사용한 코드를 계속 사용하거나 시작 코드를 다운로드하세요.
- 시작 코드에서
SleepQualityFragment
를 검사합니다. 이 클래스는 레이아웃을 확장하고 애플리케이션을 가져와binding.root
를 반환합니다. - 디자인 편집기에서 navigation.xml을 엽니다.
SleepTrackerFragment
에서SleepQualityFragment
로 이동하는 탐색 경로가 있고SleepQualityFragment
에서SleepTrackerFragment
로 다시 돌아오는 탐색 경로가 있습니다. - navigation.xml의 코드를 검사합니다. 특히
sleepNightKey
이라는 이름의<argument>
를 찾습니다.
사용자가SleepTrackerFragment
에서SleepQualityFragment,
로 이동하면 앱은 업데이트해야 하는 밤에sleepNightKey
을SleepQualityFragment
에 전달합니다.
2단계: 수면의 질 추적을 위한 탐색 추가
탐색 그래프에는 이미 SleepTrackerFragment
에서 SleepQualityFragment
로 이동했다가 다시 돌아오는 경로가 포함되어 있습니다. 하지만 한 프래그먼트에서 다음 프래그먼트로의 탐색을 구현하는 클릭 핸들러는 아직 코딩되지 않았습니다. 이제 ViewModel
에 해당 코드를 추가합니다.
클릭 핸들러에서 앱이 다른 대상으로 이동할 때 변경되는 LiveData
를 설정합니다. 프래그먼트가 이 LiveData
를 관찰합니다. 데이터가 변경되면 프래그먼트가 대상으로 이동하고 뷰 모델에 완료되었음을 알려 상태 변수를 재설정합니다.
SleepTrackerViewModel
를 엽니다. 사용자가 중지 버튼을 탭하면 앱이SleepQualityFragment
로 이동하여 품질 평가를 수집하도록 탐색을 추가해야 합니다.SleepTrackerViewModel
에서 앱이SleepQualityFragment
로 이동할 때 변경되는LiveData
를 만듭니다. 캡슐화를 사용하여LiveData
의 가져올 수 있는 버전만ViewModel
에 노출합니다.
이 코드는 클래스 본문의 최상위 수준에 어디든 배치할 수 있습니다.
private val _navigateToSleepQuality = MutableLiveData<SleepNight>()
val navigateToSleepQuality: LiveData<SleepNight>
get() = _navigateToSleepQuality
- 탐색을 트리거하는 변수를 재설정하는
doneNavigating()
함수를 추가합니다.
fun doneNavigating() {
_navigateToSleepQuality.value = null
}
- 중지 버튼
onStopTracking()
의 클릭 핸들러에서SleepQualityFragment
로의 탐색을 트리거합니다. 함수 끝에서 _navigateToSleepQuality
변수를launch{}
블록 내의 마지막 항목으로 설정합니다. 이 변수는night
로 설정됩니다. 이 변수에 값이 있으면 앱이SleepQualityFragment
로 이동하여 night.
을 전달합니다.
_navigateToSleepQuality.value = oldNight
- 앱이 언제 탐색해야 하는지 알 수 있도록
SleepTrackerFragment
는 _navigateToSleepQuality
를 관찰해야 합니다.SleepTrackerFragment
의onCreateView()
에서navigateToSleepQuality()
의 관찰자를 추가합니다. 이 가져오기는 모호하므로androidx.lifecycle.Observer
.
을 가져와야 합니다.
sleepTrackerViewModel.navigateToSleepQuality.observe(this, Observer {
})
- 관찰자 블록 내에서 현재 밤의 ID를 탐색하고 전달한 다음
doneNavigating()
를 호출합니다. 가져오기가 모호한 경우androidx.navigation.fragment.findNavController
을 가져옵니다.
night ->
night?.let {
this.findNavController().navigate(
SleepTrackerFragmentDirections
.actionSleepTrackerFragmentToSleepQualityFragment(night.nightId))
sleepTrackerViewModel.doneNavigating()
}
- 앱을 빌드하고 실행합니다. 시작을 탭한 다음 중지를 탭하면
SleepQualityFragment
화면으로 이동합니다. 뒤로 돌아가려면 시스템 뒤로 버튼을 사용하세요.
이 작업에서는 수면의 질을 기록하고 수면 추적기 프래그먼트로 다시 이동합니다. 디스플레이가 자동으로 업데이트되어 사용자에게 업데이트된 값을 표시해야 합니다. ViewModel
와 ViewModelFactory
를 만들고 SleepQualityFragment
를 업데이트해야 합니다.
1단계: ViewModel 및 ViewModelFactory 만들기
sleepquality
패키지에서 SleepQualityViewModel.kt를 만들거나 엽니다.sleepNightKey
및 데이터베이스를 인수로 사용하는SleepQualityViewModel
클래스를 만듭니다.SleepTrackerViewModel
의 경우와 마찬가지로 팩토리에서database
을 전달해야 합니다. 탐색에서sleepNightKey
도 전달해야 합니다.
class SleepQualityViewModel(
private val sleepNightKey: Long = 0L,
val database: SleepDatabaseDao) : ViewModel() {
}
SleepQualityViewModel
클래스 내에서Job
와uiScope
을 정의하고onCleared()
.
을 재정의합니다.
private val viewModelJob = Job()
private val uiScope = CoroutineScope(Dispatchers.Main + viewModelJob)
override fun onCleared() {
super.onCleared()
viewModelJob.cancel()
}
- 위와 동일한 패턴을 사용하여
SleepTrackerFragment
로 다시 이동하려면_navigateToSleepTracker
를 선언합니다.navigateToSleepTracker
및doneNavigating()
.
구현
private val _navigateToSleepTracker = MutableLiveData<Boolean?>()
val navigateToSleepTracker: LiveData<Boolean?>
get() = _navigateToSleepTracker
fun doneNavigating() {
_navigateToSleepTracker.value = null
}
- 모든 수면의 질 이미지에 사용할 클릭 핸들러
onSetSleepQuality()
를 만듭니다.
이전 Codelab과 동일한 코루틴 패턴을 사용합니다.
uiScope
에서 코루틴을 실행하고 I/O 디스패처로 전환합니다.sleepNightKey
를 사용하여tonight
을 가져옵니다.- 수면의 질을 설정합니다.
- 데이터베이스를 업데이트합니다.
- 탐색을 트리거합니다.
아래 코드 샘플에서는 서로 다른 컨텍스트에서 데이터베이스 작업을 팩터링하는 대신 클릭 핸들러에서 모든 작업을 실행합니다.
fun onSetSleepQuality(quality: Int) {
uiScope.launch {
// IO is a thread pool for running operations that access the disk, such as
// our Room database.
withContext(Dispatchers.IO) {
val tonight = database.get(sleepNightKey) ?: return@withContext
tonight.sleepQuality = quality
database.update(tonight)
}
// Setting this state variable to true will alert the observer and trigger navigation.
_navigateToSleepTracker.value = true
}
}
sleepquality
패키지에서SleepQualityViewModelFactory.kt
를 만들거나 열고 아래와 같이SleepQualityViewModelFactory
클래스를 추가합니다. 이 클래스는 이전에 본 것과 동일한 상용구 코드 버전을 사용합니다. 계속하기 전에 코드를 검사하세요.
class SleepQualityViewModelFactory(
private val sleepNightKey: Long,
private val dataSource: SleepDatabaseDao) : ViewModelProvider.Factory {
@Suppress("unchecked_cast")
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(SleepQualityViewModel::class.java)) {
return SleepQualityViewModel(sleepNightKey, dataSource) as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
}
2단계: SleepQualityFragment 업데이트
SleepQualityFragment.kt
를 엽니다.onCreateView()
에서application
를 가져온 후 내비게이션과 함께 제공된arguments
를 가져와야 합니다. 이러한 인수는SleepQualityFragmentArgs
에 있습니다. 번들에서 추출해야 합니다.
val arguments = SleepQualityFragmentArgs.fromBundle(arguments!!)
- 그런 다음
dataSource
를 가져옵니다.
val dataSource = SleepDatabase.getInstance(application).sleepDatabaseDao
dataSource
와sleepNightKey
를 전달하여 팩토리를 만듭니다.
val viewModelFactory = SleepQualityViewModelFactory(arguments.sleepNightKey, dataSource)
ViewModel
참조를 가져옵니다.
val sleepQualityViewModel =
ViewModelProviders.of(
this, viewModelFactory).get(SleepQualityViewModel::class.java)
- 바인딩 객체에
ViewModel
를 추가합니다. (바인딩 객체에 오류가 표시되면 지금은 무시하세요.)
binding.sleepQualityViewModel = sleepQualityViewModel
- 관찰자를 추가합니다. 메시지가 표시되면
androidx.lifecycle.Observer
를 가져옵니다.
sleepQualityViewModel.navigateToSleepTracker.observe(this, Observer {
if (it == true) { // Observed state is true.
this.findNavController().navigate(
SleepQualityFragmentDirections.actionSleepQualityFragmentToSleepTrackerFragment())
sleepQualityViewModel.doneNavigating()
}
})
3단계: 레이아웃 파일 업데이트 및 앱 실행
fragment_sleep_quality.xml
레이아웃 파일을 엽니다.<data>
블록에SleepQualityViewModel
변수를 추가합니다.
<data>
<variable
name="sleepQualityViewModel"
type="com.example.android.trackmysleepquality.sleepquality.SleepQualityViewModel" />
</data>
- 6개의 수면 품질 이미지 각각에 아래와 같은 클릭 핸들러를 추가합니다. 품질 등급을 이미지와 일치시킵니다.
android:onClick="@{() -> sleepQualityViewModel.onSetSleepQuality(5)}"
- 프로젝트를 정리하고 다시 빌드합니다. 이렇게 하면 바인딩 객체의 오류가 해결됩니다. 그렇지 않으면 캐시를 지우고 (File > Invalidate Caches / Restart) 앱을 다시 빌드합니다.
축하합니다. 코루틴을 사용하여 완전한 Room
데이터베이스 앱을 빌드했습니다.
이제 앱이 제대로 작동합니다. 사용자는 원하는 만큼 시작 및 중지를 탭할 수 있습니다. 사용자가 중지를 탭하면 수면의 질을 입력할 수 있습니다. 사용자가 지우기를 탭하면 모든 데이터가 백그라운드에서 자동으로 삭제됩니다. 하지만 모든 버튼이 항상 사용 설정되어 클릭할 수 있으므로 앱이 중단되지는 않지만 사용자가 불완전한 수면을 만들 수 있습니다.
이 마지막 작업에서는 변환 맵을 사용하여 사용자가 올바른 선택만 할 수 있도록 버튼 표시 상태를 관리하는 방법을 알아봅니다. 모든 데이터가 삭제된 후 친근한 메시지를 표시하는 데도 비슷한 방법을 사용할 수 있습니다.
1단계: 버튼 상태 업데이트
처음에는 Start(시작) 버튼만 사용 설정되어 클릭할 수 있도록 버튼 상태를 설정해야 합니다.
사용자가 시작을 탭하면 중지 버튼이 사용 설정되고 시작은 사용 설정되지 않습니다. 지우기 버튼은 데이터베이스에 데이터가 있는 경우에만 사용 설정됩니다.
fragment_sleep_tracker.xml
레이아웃 파일을 엽니다.- 각 버튼에
android:enabled
속성을 추가합니다.android:enabled
속성은 버튼이 사용 설정되었는지 여부를 나타내는 불리언 값입니다. (사용 설정된 버튼은 탭할 수 있지만 사용 중지된 버튼은 탭할 수 없습니다.) 잠시 후에 정의할 상태 변수의 값을 속성에 부여합니다.
start_button
:
android:enabled="@{sleepTrackerViewModel.startButtonVisible}"
stop_button
:
android:enabled="@{sleepTrackerViewModel.stopButtonVisible}"
clear_button
:
android:enabled="@{sleepTrackerViewModel.clearButtonVisible}"
SleepTrackerViewModel
를 열고 세 개의 해당 변수를 만듭니다. 각 변수에 변환을 할당하여 변수를 테스트합니다.
tonight
가null
이면 시작 버튼이 사용 설정되어야 합니다.tonight
이null
이 아닌 경우 중지 버튼이 사용 설정되어야 합니다.- 지우기 버튼은
nights
(따라서 데이터베이스)에 수면 밤이 포함된 경우에만 사용 설정해야 합니다.
val startButtonVisible = Transformations.map(tonight) {
it == null
}
val stopButtonVisible = Transformations.map(tonight) {
it != null
}
val clearButtonVisible = Transformations.map(nights) {
it?.isNotEmpty()
}
- 앱을 실행하고 버튼을 실험해 보세요.
2단계: 스낵바를 사용하여 사용자에게 알림
사용자가 데이터베이스를 삭제한 후 Snackbar
위젯을 사용하여 사용자에게 확인을 표시합니다. 스낵바는 화면 하단의 메시지를 통해 작업에 대한 간단한 의견을 제공합니다. 스낵바는 제한 시간이 지나거나, 사용자가 화면의 다른 곳에서 상호작용하거나, 사용자가 스낵바를 화면에서 스와이프하면 사라집니다.
스낵바를 표시하는 것은 UI 작업이므로 프래그먼트에서 발생해야 합니다. 스낵바를 표시할지 여부는 ViewModel
에서 결정합니다. 데이터가 삭제될 때 스낵바를 설정하고 트리거하려면 탐색을 트리거할 때와 동일한 기법을 사용하면 됩니다.
SleepTrackerViewModel
에서 캡슐화된 이벤트를 만듭니다.
private var _showSnackbarEvent = MutableLiveData<Boolean>()
val showSnackBarEvent: LiveData<Boolean>
get() = _showSnackbarEvent
- 그런 다음
doneShowingSnackbar()
를 구현합니다.
fun doneShowingSnackbar() {
_showSnackbarEvent.value = false
}
SleepTrackerFragment
의onCreateView()
에 관찰자를 추가합니다.
sleepTrackerViewModel.showSnackBarEvent.observe(this, Observer { })
- 관찰자 블록 내에서 스낵바를 표시하고 즉시 이벤트를 재설정합니다.
if (it == true) { // Observed state is true.
Snackbar.make(
activity!!.findViewById(android.R.id.content),
getString(R.string.cleared_message),
Snackbar.LENGTH_SHORT // How long to display the message.
).show()
sleepTrackerViewModel.doneShowingSnackbar()
}
SleepTrackerViewModel
에서onClear()
메서드의 이벤트를 트리거합니다. 이렇게 하려면launch
블록 내에서 이벤트 값을true
로 설정합니다.
_showSnackbarEvent.value = true
- 앱을 빌드하고 실행합니다.
Android 스튜디오 프로젝트: TrackMySleepQualityFinal
이 앱에서 수면의 질 추적을 구현하는 것은 새로운 키로 익숙한 음악을 연주하는 것과 같습니다. 세부사항은 변경되지만 이 과정의 이전 Codelab에서 수행한 기본 패턴은 동일하게 유지됩니다. 이러한 패턴을 알고 있으면 기존 앱의 코드를 재사용할 수 있으므로 코딩이 훨씬 빨라집니다. 지금까지 이 과정에서 사용된 패턴은 다음과 같습니다.
ViewModel
및ViewModelFactory
를 만들고 데이터 소스를 설정합니다.- 탐색을 트리거합니다. 관심사를 분리하려면 클릭 핸들러를 뷰 모델에 넣고 탐색을 프래그먼트에 넣으세요.
LiveData
를 사용하여 캡슐화하여 상태 변경을 추적하고 이에 대응합니다.LiveData
와 함께 변환을 사용합니다.- 싱글톤 데이터베이스를 만듭니다.
- 데이터베이스 작업을 위한 코루틴 설정
탐색 트리거
탐색 파일에서 프래그먼트 간에 가능한 탐색 경로를 정의합니다. 한 프래그먼트에서 다음 프래그먼트로의 탐색을 트리거하는 방법에는 여러 가지가 있습니다. 예를 들면 다음과 같습니다.
- 대상 프래그먼트로의 탐색을 트리거하는
onClick
핸들러를 정의합니다. - 또는 한 프래그먼트에서 다음 프래그먼트로의 탐색을 사용 설정하려면 다음을 실행하세요.
- 탐색이 발생해야 하는지 기록하는
LiveData
값을 정의합니다. - 해당
LiveData
값에 관찰자를 연결합니다. - 그러면 탐색을 트리거해야 하거나 탐색이 완료될 때마다 코드가 해당 값을 변경합니다.
android:enabled 속성 설정
android:enabled
속성은TextView
에 정의되어 있으며Button
를 비롯한 모든 하위 클래스에 의해 상속됩니다.android:enabled
속성은View
가 사용 설정되어 있는지 여부를 결정합니다. '사용 설정됨'의 의미는 하위 클래스에 따라 다릅니다. 예를 들어 사용 설정되지 않은EditText
는 사용자가 포함된 텍스트를 수정하지 못하도록 하고 사용 설정되지 않은Button
는 사용자가 버튼을 탭하지 못하도록 합니다.enabled
속성은visibility
속성과 다릅니다.- 변환 맵을 사용하여 다른 객체 또는 변수의 상태에 따라 버튼의
enabled
속성 값을 설정할 수 있습니다.
이 Codelab에서 다루는 기타 사항은 다음과 같습니다.
- 사용자에게 알림을 트리거하려면 탐색을 트리거하는 데 사용하는 것과 동일한 기법을 사용하면 됩니다.
Snackbar
를 사용하여 사용자에게 알릴 수 있습니다.
Udacity 과정:
Android 개발자 문서:
이 섹션에는 강사가 진행하는 과정의 일부로 이 Codelab을 진행하는 학생에게 출제할 수 있는 과제가 나열되어 있습니다. 다음 작업은 강사가 결정합니다.
- 필요한 경우 과제를 할당합니다.
- 과제 제출 방법을 학생에게 알립니다.
- 과제를 채점합니다.
강사는 이러한 추천을 원하는 만큼 사용할 수 있으며 적절하다고 생각되는 다른 과제를 출제해도 됩니다.
이 Codelab을 직접 진행하는 경우 이러한 과제를 자유롭게 사용하여 배운 내용을 테스트해 보세요.
질문에 답하세요
질문 1
앱이 한 프래그먼트에서 다음 프래그먼트로의 탐색을 트리거하도록 하는 한 가지 방법은 LiveData
값을 사용하여 탐색을 트리거할지 여부를 나타내는 것입니다.
gotoBlueFragment
이라는 LiveData
값을 사용하여 빨간색 프래그먼트에서 파란색 프래그먼트로 탐색을 트리거하는 단계는 무엇인가요? 해당하는 항목을 모두 선택해 주세요.
ViewModel
에서LiveData
값gotoBlueFragment
를 정의합니다.RedFragment
에서gotoBlueFragment
값을 확인합니다.observe{}
코드를 구현하여 적절한 경우BlueFragment
로 이동한 다음gotoBlueFragment
값을 재설정하여 탐색이 완료되었음을 나타냅니다.- 앱이
RedFragment
에서BlueFragment
로 이동해야 할 때마다 코드가gotoBlueFragment
변수를 탐색을 트리거하는 값으로 설정해야 합니다. - 사용자가 클릭하여
BlueFragment
로 이동하는View
에 대해 코드가onClick
핸들러를 정의해야 합니다. 여기서onClick
핸들러는goToBlueFragment
값을 관찰합니다.
질문 2
LiveData
를 사용하여 Button
가 사용 설정 (클릭 가능)되었는지 여부를 변경할 수 있습니다. 앱이 다음을 충족하도록 UpdateNumber
버튼을 변경하려면 어떻게 해야 할까요?
myNumber
값이 5보다 크면 버튼이 사용 설정됩니다.myNumber
이 5 이하이면 버튼이 사용 설정되지 않습니다.
UpdateNumber
버튼이 포함된 레이아웃에 다음과 같이 NumbersViewModel
의 <data>
변수가 포함되어 있다고 가정합니다.
<data> <variable name="NumbersViewModel" type="com.example.android.numbersapp.NumbersViewModel" /> </data>
레이아웃 파일의 버튼 ID가 다음과 같다고 가정합니다.
android:id="@+id/update_number_button"
그 밖에 해야 할 일은 무엇인가요? 해당하는 항목을 모두 선택해 주세요.
NumbersViewModel
클래스에서 숫자를 나타내는LiveData
변수myNumber
을 정의합니다. 또한myNumber
변수에서Transform.map()
를 호출하여 값이 설정되는 변수를 정의합니다. 이 변수는 숫자가 5보다 큰지 여부를 나타내는 불리언을 반환합니다.
구체적으로ViewModel
에 다음 코드를 추가합니다.
val myNumber: LiveData<Int>
val enableUpdateNumberButton = Transformations.map(myNumber) {
myNumber > 5
}
- XML 레이아웃에서
update_number_button button
의android:enabled
속성을NumberViewModel.enableUpdateNumbersButton
로 설정합니다.
android:enabled="@{NumbersViewModel.enableUpdateNumberButton}"
NumbersViewModel
클래스를 사용하는Fragment
에서 버튼의enabled
속성에 관찰자를 추가합니다.
구체적으로Fragment
에 다음 코드를 추가합니다.
// Observer for the enabled attribute
viewModel.enabled.observe(this, Observer<Boolean> { isEnabled ->
myNumber > 5
})
- 레이아웃 파일에서
update_number_button button
의android:enabled
속성을"Observable"
로 설정합니다.
다음 강의 시작:
이 과정의 다른 Codelab 링크는 Android Kotlin 기초 Codelab 방문 페이지를 참고하세요.