Jetpack Compose 및 Datastore를 사용한 양방향 흐름
본문 바로가기
카테고리 없음

Jetpack Compose 및 Datastore를 사용한 양방향 흐름

by Emily Blunt 2022. 5. 2.
반응형

Jetpack Compose 및 Datastore를 사용한 양방향 흐름

 

Android 프로젝트에서 MVVM을 사용하는 방법

Unsplash의 Zhipeng Ya 사진

방금 Jetpack Compose API와 데이터 저장소를 가지고 놀기 시작했는데 사용하기 정말 편리합니다.

양방향(2-way) 데이터 흐름이 있는 간단한 데모 앱을 만들어 보겠습니다.

Jetpack compose 라이브러리와 Datastore 라이브러리를 사용하여 MVVM을 작은 프로젝트의 아키텍처로 사용할 것입니다. 코루틴은 여기에 자연스럽게 포함됩니다. 시작하자!

데모 앱은 다음과 같습니다.

주요 아키텍처는 다음과 같습니다.

양방향 흐름이 어떻게 생겼는지 알 수 있습니다. 왼쪽에는 사용자 상호 작용 시 데이터가 변경된 보기가 있습니다. ViewModel 이 변경된 데이터를 데이터 저장소로 전달하고 거기에서 새 데이터가 유지됩니다.

데이터가 유지되는 즉시 Datastore 새로운 데이터 흐름을 내보내고 다시 View로 전달되고 UI를 업데이트할 수 있습니다. 이것은 정말 간단한 솔루션이며 뷰를 구독/관찰/바인딩하기 위한 상용구 코드가 필요하지 않습니다. ViewModels.

UI 기회는 흐름 데이터의 모든 방출과 함께 트리거됩니다. 그리고 이것은 UI가 변경될 때마다 트리거됩니다. Datastore 기회.

//Composable UI element that handles onTextChangeAction
@Composable
fun DataStorePlaygroundActivityComponent(
stringData: String,
keyboardController: SoftwareKeyboardController?,
onTextChangeAction: (dataString: String) -> Unit
) {
val textAnswerState = remember {
mutableStateOf("")
}
JetPackPlaygroundAppTheme {
Surface(color = MaterialTheme.colors.background) {
Column(Modifier.fillMaxSize()) {
Title("DataStore Playground")
Spacer(modifier = Modifier.height(16.dp))
NormalText("Data: $stringData")
Spacer(modifier = Modifier.height(32.dp))
TextFieldSingleLine(
textAnswerState,
"enter settings text",
keyboardController,
onTextChangeAction
)
}
}
}
}//Activity|Fragment view setting the composable
DataStorePlaygroundActivityComponent(
stringData,
LocalSoftwareKeyboardController.current
) { dataString ->
dataStoreViewModel?.saveDefaultText(dataString)
}//ViewModel interaction with the datastore.viewModelScope.launch {
localDataStore.saveDefaultText(defaultText)
}

위에 표시된 코드는 UI 요소가 배치되는 방법을 보여줍니다. 하나의 구성 가능한 요소가 정의되어 있습니다. DataStorePlaygroundActivityComponent 저장된 텍스트가 텍스트 보기에 표시되고 사용자 상호 작용이 완료될 때 호출되는 작업(TextField 구성 요소의 텍스트 변경)도 있습니다. 그 후, ViewModel 새 값을 데이터 저장소로 전달하기만 하면 됩니다.

새 값이 데이터 저장소에 유지되자마자 새 값이 즉시 내보내지고 뷰에 전파됩니다. 다음은 몇 가지 코드 조각입니다.

//Flow data from the datastore
override val customTextData: Flow
get() = App.applicationContext().dataStore.data
.map { preferences ->
preferences[customTextKey] ?: CUSTOM_TEXT_SETTINGS_DEFAULT_VALUE
}//Listening the the flow within the ViewModel
init {
viewModelScope.launch {
localDataStore.customTextData.collect { data ->
mutableFlowData.value = LatestDataUiState.Success(data)
}
}
}
//Data class for UI state
sealed class LatestDataUiState {
data class Success(val tempString: String): LatestDataUiState()
data class Error(val exception: Throwable): LatestDataUiState()
}//View logic
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
dataStoreViewModel?.uiStateFlow?.collect { uiState ->
// New value received
when (uiState) {
is LatestDataUiState.Success -> showSuccessUI(uiState.tempString)
is LatestDataUiState.Error -> showErrorUI(uiState.exception)
}
}
}
}

위에서 잘라낸 코드는 뷰가 데이터 흐름과 연결되는 방식과 새 UI 데이터가 수신될 때 재작성이 발생하는 방식을 보여줍니다.

그리고 그게 다야! 코드는 다른 패턴에 비해 정말 작습니다. 전체 코드는 여기에서 찾을 수 있습니다.

Want to Connect?If you are interested I’ve developed a simple puzzle app using Jetpack components. Check it out here.
반응형

댓글0