elvis 演算子を使用して設定マネージャーにデフォルト値を設定したにもかかわらず、DataStore が null を返し続けます。また、キーと値のペアを設定するための編集機能が呼び出されていないため、データストアが一般的に適切に設定されているかどうかさえわかりません。ただし、ブレークポイントを使用しているときにクラスが変数として表示されるため、クラスが適切に挿入されていると確信しています。
基本的val countryCode = viewModel.countrySettings.value
にViewModelでは常にnullを返します
PreferencesManager クラス
const val TAG = "PreferencesManager"
const val DEFAULT_COUNTRY_PREFERENCE = "us"
const val DEFAULT_CATEGORY_PREFERENCE = "general"
private val Context.dataStore by preferencesDataStore(name = PREFERENCES_NAME)
@Singleton
class PreferencesManager @Inject constructor(@ApplicationContext appContext: Context) {
private val preferencesDataStore = appContext.dataStore
//Pairs are separated but I'll create an appropriate data class later.
val countrySettings = preferencesDataStore.data
.catch { exception ->
if (exception is IOException) {
Log.e(TAG, "Error while trying to read user preferences", exception)
emit(emptyPreferences())
} else {
throw exception
}
}
.map { preference ->
val country = preference[PreferenceKeys.COUNTRY] ?: DEFAULT_COUNTRY_PREFERENCE
country
}
val categorySettings = preferencesDataStore.data
.catch { exception ->
if (exception is IOException) {
Log.e(TAG, "Error while trying to read user preferences", exception)
emit(emptyPreferences())
} else {
throw exception
}
}
.map { preferences ->
val category = preferences[PreferenceKeys.CATEGORY] ?: DEFAULT_CATEGORY_PREFERENCE
category
}
suspend fun setCountryPreference(country: String) {
preferencesDataStore.edit { preference ->
preference[PreferenceKeys.COUNTRY] = country
}
}
suspend fun setCategoryPreference(category: String) {
preferencesDataStore.edit { preference ->
preference[PreferenceKeys.CATEGORY] = category
}
}
private object PreferenceKeys {
val COUNTRY = stringPreferencesKey("country")
val CATEGORY = stringPreferencesKey("category")
}
}
ビューモデル
class MainViewModel @Inject constructor(
private val repository: Repository,
private val preferencesManager: PreferencesManager
): ViewModel() {
val countrySettings = preferencesManager.countrySettings.asLiveData()
val categorySettings = preferencesManager.categorySettings.asLiveData()
/* .... */
fun setCountryPreference(country: String) {
viewModelScope.launch {
preferencesManager.setCountryPreference(country)
}
}
fun setCategoryPreference(category: String) {
viewModelScope.launch {
preferencesManager.setCategoryPreference(category)
}
}
}
断片
val viewModel: MainViewModel by activityViewModels()
private var _binding: FragmentSettingsCountryScreenBinding? = null
private val binding get() = _binding!!
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
_binding = FragmentSettingsCountryScreenBinding.bind(view)
//Using breakpoints I've noticed this function isn't even called on the preferences manager to set the value, which is weird
viewModel.setCountryPreference("us")
val countryCode = viewModel.countrySettings.value
binding.radiogroup.check(adaptPreferenceFromDataStore(countryCode!!))
binding.radiogroup.setOnCheckedChangeListener { _, checkedId ->
viewModel.setCountryPreference(adaptPreferenceToDataStore(checkedId))
}
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}