박종훈 기술블로그

[Jetpack Compose] State와 DataStore 연결하기

    https://developer.android.com/topic/libraries/architecture/datastore

    DataStore 라는것이 생겼다.

    옛날에는 SharedPreference 라는 것을 썼었는데 더 모던해진 애로 이해하면 될 것 같다.
    정확한 설명은 다음과 같다.

    Jetpack DataStore is a data storage solution that allows you to store key-value pairs or typed objects with protocol buffers. DataStore uses Kotlin coroutines and Flow to store data asynchronously, consistently, and transactionally.

    아무튼 이 애를 Compose 환경에서 쓸 수 있도록 연결한 과정에 대해서 설명한다.


    설정 페이지를 만들기 위해서 아래와 같은 작업을 진행했으며
    목표는 checkbox를 선택했을 때 해당 선택 정보가 로컬 기기에 저장되기를 바랬다.

    그리고 이를 위해서 Compose 와 DataStore 를 연결해야 했다.

    일단은 DataStore를 만드는 부분이다.

    SettingDataStore.kt

    class SettingDataStore {
        companion object {
            val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "settings")
            val ignore_no_content_key = booleanPreferencesKey("ignore_no_content")
            val ignore_duplicated_key = booleanPreferencesKey("ignore_duplicated")
        }
    }

    DataStore의 이름을 정해주고 필요한 key들을 생성해둔다.

    SettingActivity.kt

    @Composable
    fun SettingPage() {
        val dataStore = (LocalContext.current).dataStore
    
        val ignoreNoContentState = remember { mutableStateOf(false) }
        val ignoreNoDuplicatedState = remember { mutableStateOf(false) }
    
        LaunchedEffect(Unit) {
            dataStore.data.collect { preferences ->
                ignoreNoContentState.value = preferences[ignore_no_content_key] ?: false
                ignoreNoDuplicatedState.value = preferences[ignore_duplicated_key] ?: false
            }
        }
    
        LaunchedEffect(ignoreNoContentState.value) {
            dataStore.edit { preferences ->
                preferences[ignore_no_content_key] = ignoreNoContentState.value
            }
        }
    
        LaunchedEffect(ignoreNoDuplicatedState.value) {
            dataStore.edit { preferences ->
                preferences[ignore_duplicated_key] = ignoreNoDuplicatedState.value
            }
        }
        
        ... 중략 ...
    }

    Checkbox(
        checked = ignoreNoContentState.value,
        onCheckedChange = { checked ->
            run {
                ignoreNoContentState.value = checked
            }
        }
    )

    이렇게 만들어주면 CheckBox에서 값이 변경되었을 때 DataStore에도 반영이 되게 된다.

    categories: 개발

    tags: android , jetpack , jetpack compose , compose , datastore , state , checkbox