Jetpack Compose : LiveData, Flow

aram·2021년 10월 30일
0

LiveData

Library 적용

build.gradle[app] 에 runtime-livedata 추가

implementation "androidx.compose.runtime:runtime-livedata:$compose_version"

사용하기

ViewModel

private val _myModels = MutableLiveData<MyViewModel>()
val myModels: LiveData<MyViewModel> = _deal

View

observableAsState() 로 state 를 관찰하여 가져온다.

private val viewModel = ViewModelProvider(this).get(MainViewModel::class.java)

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContent {
        ComposableTheme {
            val myModels = viewModel.myModels.obverseAsState().value ?: emptyList()
            val clickedModel = viewModel.clickedModel.observeAsState().value
        }
    }
}

Flow

사용하기

ViewModel

val pager: Flow<PagingData<MyDocument>> = Pager(PagingConfig(pageSize = 20)) {
    MySource(MyRepository())
}.flow.cachedIn(viewModelScope)

스크롤의 상태를 저장하고 싶다면 cachedIn() 을 쓴다.

View

loadState에 따라 화면을 다르게 구현한다.

import androidx.paging.compose.collectAsLazyPagingItems
import androidx.paging.compose.items

@Composable
fun MessageList(myViewModel: MyViewModel) {
    val pager = myViewModel.pager
    val lazyPagingItems = pager.flow.collectAsLazyPagingItems()

    LazyColumn {
        items(
          items = lazyPagingItems,
          // The key is important so the Lazy list can remember your
          // scroll position when more items are fetched!
          key = { message -> message.id }
        ) { message ->
            if (message != null) {
                MessageRow(message)
            } else {
                MessagePlaceholder()
            }
        }
        
        pager.apply {
            loadState.refresh is LoadState.Loading -> {
                item { LoadingBar() }
            }
            loadState.append is LoadState.Loading -> {
                item { LoadingItem() }
            }
            loadState.refresh is LoadState.Error -> {
                val e = pager.loadState.refresh as LoadState.Error
                item {
                    ErrorItem(
                        message = e.error.localizedMessage ?: "Error!",
                        modifier = Modifier.fillParentMaxSize(),
                        onClickRetry = { retry() }
                    )
                }
            }
            loadState.append is LoadState.Error -> {
                val e = pager.loadState.append as LoadState.Error
                item {
                    ErrorItem(
                        message = e.error.localizedMessage ?: "Error!",
                        onClickRetry = { retry() }
                    )
                }
            }
            loadState.refresh is LoadState.NotLoading && loadState.append.endOfPaginationReached -> {
                if (this.itemCount == 0) {
                    item {
                        NoLoadData()
                    }
                }
            }
        }
    }
}

마무리

여러 아티클을 읽다보면 안드로이드에 종속적인 liveData 보다, 코틀린 순수 라이브러리인 stateFlow가 더 좋다고 말하고 있다. liveData가 장기적으로 봤을 때 deprecated 되는 것이 아니냐는 소문까지 돌고 있다고..

우선 이런 의견이 있구나, 참고만 하자.

0개의 댓글