TIL) 230412

Hanseul Lee·2023년 4월 12일
0

TIL

목록 보기
23/23

Data 클래스 copy()

copy() 함수는 기본적으로 데이터 클래스의 모든 인스턴스에 제공된다. 이 함수는 일부 속성을 변경하지만 나머지 속성은 변경하지 않고 그대로 두기 위해 객체를 복사하는 데 사용된다.

// Data class
data class User(val name: String = "", val age: Int = 0)

// Data class instance
val jack = User(name = "Jack", age = 1)

// A new instance is created with its age property changed, rest of the properties unchanged.
val olderJack = jack.copy(age = 2)

Room에서 가져온 값에 연산을 하려면 Flow가 아닌 LiveData를 활용하자

DataBinding을 활용해서 viewModel의 값을 활용하는 코드다. viewModel의 getAllChatList의 크기를 삼항연산자를 이용해 BindingAdpater로 전달하여 visibility를 조절하고 있다.

// layout.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>

        <variable
            name="listViewModel"
            type="hs.project.cof.presentation.viewModels.ChatListViewModel" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".presentation.view.chatList.ChatListFragment">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:text="저장한 메시지가 없습니다."
            android:gravity="center"
						app:visibleMessage="@{listViewModel.getAllChatList.size() > 0 ? false : true}"/>

        ...
    </androidx.constraintlayout.widget.ConstraintLayout>

</layout>
// bindingApdater.kt

@BindingAdapter("isVisible")
fun isVisible(textView: TextView, isVisible: Boolean) {
    Log.d("CHECK_VISIBLE","$isVisible")
    if (isVisible) {
        textView.visibility = View.VISIBLE
    } else {
        textView.visibility = View.GONE
    }
}
// dao.kt
@Query("SELECT count(*) AS chatListCount FROM chatList")
    fun getAllChatListSize(): LiveData<Int>
// repository.kt

val getChatListSize: Int = chatListDao.getAllChatListSize()
// viewmodel.kt

val getChatListCount: Int = repository.getChatListSize

그런데 막상 코드를 실행하니 아래와 같은 오류가 났다.

💡 java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.

메인 스레드가 아닌 다른 스레드에서 쿼리를 실행하라는 경고다. 그래서 코루틴 Flow를 사용하기로 하고, IntFlow<Int>로 바꿨더니 다음 오류가 나왔다.

💡 error: bad operand types for binary operator '>' listViewModelGetChatCountInt0 = (listViewModelGetChatCount) > (0); ^ first type: Flow second type: int

Flow는 비동기로 값을 제공하기 때문에 연산을 진행할 수 없다. 그래서 Flow<Int> 값을 연산이 가능하도록 바꿔줘야 하기 때문에 LiveData를 활용했다.

0개의 댓글