[英]Wait for Preferences Datastore to retrieve data from preferences datastore in workmanager
[英]Return null when try to read data from preferences datastore
我的应用程序是在我选择不同的语言时更改文本。 我还没有。 我很难从数据存储首选项管理器中读取“语言”和“位置”。 现在的问题是,当我尝试阅读“语言”和“位置”时,我得到了 null。
当我单击底部工作表中的一个单选按钮并退出时,然后再次单击底部工作表以查看我的最爱是否仍然处于选中状态。 底部表格保持清晰,我最喜欢的语言不记得我刚刚单击的语言,原因是它无法从首选项中读取数据并返回“null”
我是 Android 开发的新手。 我尝试过“观察”,但我无法正确使用语法。 希望任何人都可以帮助我找到问题所在。 非常感谢。
KC
最喜欢的语言片段
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val binding = FavouriteBottomSheetBinding.bind(view)
// Return null when trying to read data from PreferenceManager
val getFavouriteLanguage = viewModel.onFavouriteLanguage.value
// Return null when trying to read data from PreferenceManager
val getFavouritePosition = viewModel.onFavouritePosition.value
val favouriteAdapter = FavouriteAdapter(this, getFavouriteLanguage, getFavouritePosition)
binding.apply {
favouriteLanguageList.apply {
adapter = favouriteAdapter
layoutManager = LinearLayoutManager(requireContext())
}
}
viewModel.favouriteLanguage.observe(viewLifecycleOwner) {
favouriteAdapter.submitList(it)
}
}
override fun onFavouriteLanguageClick(selectedFavouriteLanguage: String, position: Int) {
viewModel.onSelectedFavouriteLanguage(selectedFavouriteLanguage)
viewModel.onSelectedFavouritePosition(position)
d("favouritebuttonclick", "$selectedFavouriteLanguage, $position")
}
}
最喜欢的语言查看 Model
@HiltViewModel
class FavouriteViewModel @Inject constructor(
languageDao: LanguageDao,
private val preferencesManager: PreferencesManager
) : ViewModel() {
val favouriteLanguage = languageDao.getFavouriteLanguageByName().asLiveData()
// Trying to read the data from preference manager for language and position
val onFavouriteLanguage = preferencesManager.favouriteLanguageFlow.asLiveData()
val onFavouritePosition = preferencesManager.favouritePositionFlow.asLiveData()
fun onSelectedFavouriteLanguage(selectedFavouriteLanguage: String) = viewModelScope.launch {
d("viewmodelvariable", selectedFavouriteLanguage)
preferencesManager.updateSelectedFavouriteLanguage(selectedFavouriteLanguage)
}
fun onSelectedFavouritePosition(selectedFavouritePosition: Int) = viewModelScope.launch {
d("viewmodelvariable", "$selectedFavouritePosition")
preferencesManager.updateSelectedFavouritePosition(selectedFavouritePosition)
}
}
首选项管理器
@Singleton
class PreferencesManager @Inject constructor(@ApplicationContext context: Context) {
private val dataStore = context.dataStore
val preferencesFlow = dataStore.data
.catch { exception ->
if (exception is IOException) {
Log.e(TAG, "Error reading preferences", exception)
emit(emptyPreferences())
} else {
throw exception
}
}
.map { preferences ->
val sortOrder = SortOrder.valueOf(
preferences[PreferencesKeys.SORT_ORDER] ?: SortOrder.BY_NAME.name
)
val hideSelectedLanguage = preferences[PreferencesKeys.HIDE_SELECTED_LANGUAGE] ?: false
FilterPreferences(sortOrder, hideSelectedLanguage)
}
suspend fun updateSortOrder(sortOrder: SortOrder) {
dataStore.edit { preferences ->
preferences[PreferencesKeys.SORT_ORDER] = sortOrder.name
}
}
suspend fun updateHideSelectedLanguage(hideSelectedLanguage: Boolean) {
dataStore.edit { preferences ->
preferences[PreferencesKeys.HIDE_SELECTED_LANGUAGE] = hideSelectedLanguage
}
}
suspend fun updateSelectedFavouriteLanguage(selectedFavouriteLanguage: String) {
Log.d("preferencevariable", selectedFavouriteLanguage)
dataStore.edit { preferences ->
preferences[PreferencesKeys.SELECTED_FAVOURITE_LANGUAGE] = selectedFavouriteLanguage
}
}
suspend fun updateSelectedFavouritePosition(selectedFavouritePosition: Int) {
Log.d("preferencevariable", selectedFavouritePosition.toString())
dataStore.edit { preferences ->
preferences[PreferencesKeys.SELECTED_FAVOURITE_POSITION] =
selectedFavouritePosition
}
}
// Try to read language from datastore
val favouriteLanguageFlow: Flow<String?> = dataStore.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 ->
preferences[PreferencesKeys.SELECTED_FAVOURITE_LANGUAGE]
}
// Try to read language position from datastore
val favouritePositionFlow: Flow<Int?> = dataStore.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 ->
preferences[PreferencesKeys.SELECTED_FAVOURITE_POSITION]
}
private object PreferencesKeys {
val SORT_ORDER = stringPreferencesKey("sort_order")
val HIDE_SELECTED_LANGUAGE = booleanPreferencesKey("hide_selected_language")
val SELECTED_FAVOURITE_LANGUAGE = stringPreferencesKey("selected_favourite_language")
val SELECTED_FAVOURITE_POSITION = intPreferencesKey("selected_favourite_position")
}
}
最喜欢的语言适配器
class FavouriteAdapter(
private val listener: OnFavouriteLanguageClickListener,
favouriteLanguage: String?,
favouritePosition: Int?
) :
ListAdapter<Language, FavouriteAdapter.FavouriteViewAHolder>(DiffCallback()) {
private var selectFavouritePosition = favouritePosition
private var selectLanguage = favouriteLanguage
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FavouriteViewAHolder {
val binding =
ItemFavouriteBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return FavouriteViewAHolder(binding)
}
override fun onBindViewHolder(holder: FavouriteViewAHolder, position: Int) {
val currentItem = getItem(position)
holder.bind(currentItem, position, selectFavouritePosition, selectLanguage)
holder.favouriteLanguageRadioButton.setOnClickListener {
d("testbutton", "show test")
selectFavouritePosition = holder.adapterPosition
selectLanguage = currentItem.language
d("holderlistener", "$selectLanguage, $selectFavouritePosition")
listener.onFavouriteLanguageClick(selectLanguage!!, selectFavouritePosition!!)
notifyDataSetChanged()
}
}
inner class FavouriteViewAHolder(private val binding: ItemFavouriteBinding) :
RecyclerView.ViewHolder(binding.root) {
val favouriteLanguageRadioButton = binding.rbIsClicked
fun bind(
language: Language,
position: Int,
selectFavouritePosition: Int?,
selectLanguage: String?
) {
binding.apply {
tvFavouriteLanguage.text = language.language
d("selectFavourite", "$selectFavouritePosition")
d("selectFavourite", "$selectLanguage")
if (selectFavouritePosition == -1 && position == 0) {
favouriteLanguageRadioButton.isChecked = false
} else if (selectFavouritePosition != position && selectLanguage != language.language) {
favouriteLanguageRadioButton.isChecked = false
} else if (selectFavouritePosition == position && selectLanguage == language.language) {
favouriteLanguageRadioButton.isChecked = true
}
}
}
}
interface OnFavouriteLanguageClickListener {
fun onFavouriteLanguageClick(selectedFavouriteLanguage: String, position: Int)
}
class DiffCallback : DiffUtil.ItemCallback<Language>() {
override fun areItemsTheSame(oldItem: Language, newItem: Language) =
oldItem.id == newItem.id
override fun areContentsTheSame(oldItem: Language, newItem: Language) = oldItem == newItem
}
}
在您的 PreferenceManager 中,尝试像这样获取 dataStore 实例:
private val Context.dataStore by preferencesDataStore(
name = "dataStore_$prefsName"
)
private val dataStore: DataStore<Preferences> = context.dataStore
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.