1. Event 클래스 등록
import androidx.lifecycle.Observer
/**
* Used as a wrapper for data that is exposed via a LiveData that represents an event.
*/
open class Event<out T>(private val content: T) {
@Suppress("MemberVisibilityCanBePrivate")
var hasBeenHandled = false
private set // Allow external read but not write
/**
* Returns the content and prevents its use again.
*/
fun getContentIfNotHandled(): T? {
return if (hasBeenHandled) {
null
} else {
hasBeenHandled = true
content
}
}
/**
* Returns the content, even if it's already been handled.
*/
fun peekContent(): T = content
}
/**
* An [Observer] for [Event]s, simplifying the pattern of checking if the [Event]'s content has
* already been handled.
*
* [onEventUnhandledContent] is *only* called if the [Event]'s contents has not been handled.
*/
class EventObserver<T>(private val onEventUnhandledContent: (T) -> Unit) : Observer<Event<T>> {
override fun onChanged(event: Event<T>?) {
event?.getContentIfNotHandled()?.let {
onEventUnhandledContent(it)
}
}
}
2. ViewModel에 호출 함수 등록
fun openTask(taskId: String) {
_openTaskEvent.value = Event(taskId)
}
fun completeTask(task: Task, completed: Boolean) = viewModelScope.launch {
if (completed) {
tasksRepository.completeTask(task)
showSnackbarMessage(R.string.task_marked_complete)
} else {
tasksRepository.activateTask(task)
showSnackbarMessage(R.string.task_marked_active)
}
}
3. XML 데이터 바인딩
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<import type="android.widget.CompoundButton" />
<variable
name="task"
type="com.example.android.architecture.blueprints.todoapp.data.Task" />
<variable
name="viewmodel"
type="com.example.android.architecture.blueprints.todoapp.tasks.TasksViewModel" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:orientation="horizontal"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingBottom="@dimen/list_item_padding"
android:paddingTop="@dimen/list_item_padding"
android:onClick="@{() -> viewmodel.openTask(task.id)}">
<CheckBox
android:id="@+id/complete_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:onClick="@{(view) -> viewmodel.completeTask(task, ((CompoundButton)view).isChecked())}"
android:checked="@{task.completed}" />
<TextView
android:id="@+id/title_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="@dimen/activity_horizontal_margin"
android:layout_marginStart="@dimen/activity_horizontal_margin"
android:textAppearance="@style/TextAppearance.AppCompat.Title"
android:text="@{task.titleForList}"
app:completedTask="@{task.completed}" />
</LinearLayout>
</layout>
4. Activity 또는 Fragment에 Event 관찰 등록 클래스 등록
private fun setupNavigation() {
viewModel.openTaskEvent.observe(viewLifecycleOwner,
EventObserver {
navigateToDetailsFragment(it)
})
}
반응형
'메모 log (간단메모) > mobile' 카테고리의 다른 글
'viewTreeObserver' 뷰의 크기를 측정 (0) | 2021.01.14 |
---|---|
resource 색상 가져오기 (0) | 2020.04.21 |
'stetcho' 디버깅 (0) | 2020.03.01 |
'ForeignKey' 참고사항 (0) | 2020.02.22 |
'permission' 권한 요청 (0) | 2020.02.20 |