2024. 3. 20. 15:51ㆍIT/Android
<미리 보기>
<소스 코드>
<정리>
DataStore - 관계형 데이터를 저장할 필요가 없는 경우 사용할 수 있는 경량 데이터 저장 솔루션으로, 두 가지 주요 구현체를 제공한다.
1. Preference DataStore: 키-값 쌍의 데이터를 저장하고 일반적으로 사용자 정의 타입이 아닌 Kotlin 기본 데이터 타입을 갖는다. 레이아웃, 다크 모드와 같은 간단한 앱의 사용자 환경 설정 값을 기기에 저장할 때 고려할 수 있다.
2. Proto DataStore: 맞춤 데이터 유형을 저장하고 proto 정의를 객체 구조로 매핑하는 사전 정의된 스키마를 필요로 한다.
DataStore<Preferences>객체를 파라미터로 받아 연산을 정의하는 저장소.
class UserPreferencesRepository(
private val dataStore: DataStore<Preferences>
) {
/**
* booleanPreferencesKey():
* 불리언 타입의 키를 생성한다. <저장될 값과 동일한 타입의 키를 생성해야 한다.>
* 이름은 언더바와 소문자로 이루어진 문자열이 권장된다.
* 해당 키를 활용하여 DataStore의 값을 읽고 저장할 수 있다.
*/
private companion object {
val IS_LINEAR_LAYOUT = booleanPreferencesKey("is_linear_layout")
const val TAG = "UserPreferencesRepo" //예외를 위한 로그 메세지.
}
/**
* DataStore<Preferences>.edit():
* DataStore의 값을 변경하는 메서드.
* 해당 람다에 선언된 작업들은 순차적으로 실행되는데 하나라도 실패하면 이전에 실행된 모든 게 롤백되어 변경사항이 적용되지 않는 단일 트랜잭션으로 실행된다.
* 해당 함수가 호출되어 값이 저장되면 앱의 캐시나 데이터를 따로 삭제하지 않는 한 영구적으로 보존된다.
*/
suspend fun saveLayoutPreference(isLinearLayout: Boolean) {
dataStore.edit { preferences ->
preferences[IS_LINEAR_LAYOUT] = isLinearLayout //키를 사용하여 파라미터로 받은 값을 DataStore에 저장한다.
}
}
/**
* DataStore<Preferences>.data:
* DataStore의 값을 읽는 프로퍼타로, 파일로부터 데이터를 읽어오기 때문에 IOException 예외가 발생할 수 있다.
* Flow<Preferences>를 반환하므로 데이터의 수집/방출이 가능하다.
*/
val isLinearLayout: Flow<Boolean> = dataStore.data
.catch {
if(it is IOException) {
Log.e(TAG, "Error reading preferences.", it)
emit(emptyPreferences()) //비어 있는 Preferences 반환.
} else {
throw it
}
}
.map { preferences ->
preferences[IS_LINEAR_LAYOUT] ?: true //매칭되는 키가 없으면 널을 반환하므로 기본 값을 설정하는 것이 좋다.
} // Flow<Preferences> -> Flow<Boolean> 변환.
}
저장소 객체를 생성하는 Application 클래스.
private const val LAYOUT_PREFERENCE_NAME = "layout_preferences"
private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(
name = LAYOUT_PREFERENCE_NAME
) //DataStore<Preferences> 객체 생성.
class DessertReleaseApplication: Application() {
lateinit var userPreferencesRepository: UserPreferencesRepository
override fun onCreate() {
super.onCreate()
userPreferencesRepository = UserPreferencesRepository(dataStore)
}
}
*Preferences 컴파일 에러가 발생한다면, import한 라이브러리가 아래와 동일한지 확인 할 필요가 있다.
androidx.datastore.preferences.core.Preferences
LazyVerticalGrid의 verticalArrangement, horizontalArrangement 프로퍼티에 Arrangement.spacedBy()를 적용하면 각 항목들의 가로, 세로 간격을 한 번에 적용할 수 있다.
Text의 수정자 modifier를 이용한 설정에서 wrapContentHeight()의 파라미터로 Alignment.CenterVertically을 전달하면 wrapContentHeight()이 적용되기 전의 높이를 기준으로 수직 가운데 정렬이 가능하다.
LazyVerticalGrid(
modifier = modifier,
columns = GridCells.Fixed(3),
contentPadding = contentPadding,
verticalArrangement = Arrangement.spacedBy(dimensionResource(R.dimen.padding_medium)),
horizontalArrangement = Arrangement.spacedBy(dimensionResource(R.dimen.padding_medium))
) {
items(
items = LocalDessertReleaseData.dessertReleases,
key = { dessert -> dessert }
) { dessert ->
Card(
colors = CardDefaults.cardColors(
containerColor = MaterialTheme.colorScheme.primary
),
modifier = Modifier.height(110.dp),
shape = MaterialTheme.shapes.medium
) {
Text(
text = dessert,
maxLines = 2,
overflow = TextOverflow.Ellipsis,
modifier = Modifier
.fillMaxHeight()
.wrapContentHeight(Alignment.CenterVertically)
.padding(dimensionResource(R.dimen.padding_small))
.align(Alignment.CenterHorizontally),
textAlign = TextAlign.Center
)
}
}
}
'IT > Android' 카테고리의 다른 글
Jetpack Compose - WorkManager (0) | 2024.04.03 |
---|---|
Jetpack Compose - Room, DataStore Practice (0) | 2024.03.29 |
Jetpack Compose - Room Practice (0) | 2024.03.19 |
Jetpack Compose - Room (0) | 2024.03.19 |
Jetpack Compose - APIs Practice (0) | 2024.03.12 |