简体   繁体   English

尝试从首选项数据存储中读取数据时返回 null

[英]Return null when try to read data from preferences datastore

My app is to change the text when I choose a different language.我的应用程序是在我选择不同的语言时更改文本。 I am not there yet.我还没有。 I am having difficulty reading the "language" and "position" from the datastore preference manager.我很难从数据存储首选项管理器中读取“语言”和“位置”。 The problem now is that I get null when I try to read "language" and "position".现在的问题是,当我尝试阅读“语言”和“位置”时,我得到了 null。

When I click one of the radio buttons in the bottom sheet and exit and then click the bottom sheet again to see if my favourite remains checked.当我单击底部工作表中的一个单选按钮并退出时,然后再次单击底部工作表以查看我的最爱是否仍然处于选中状态。 The bottom sheet remains clear and my favourite language didn't remember the language I just click, the reason is that it cannot read the data from the preference and return "null"底部表格保持清晰,我最喜欢的语言不记得我刚刚单击的语言,原因是它无法从首选项中读取数据并返回“null”

在此处输入图像描述

I am newbie to Android development.我是 Android 开发的新手。 I have tried "Observe" but I cannot get the syntax right.我尝试过“观察”,但我无法正确使用语法。 Hopefully, anyone can help me to find the problem.希望任何人都可以帮助我找到问题所在。 Many thanks.非常感谢。

KC KC

Favourite Language Fragment最喜欢的语言片段

 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")
    }


}

Favourite Langauge View Model最喜欢的语言查看 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)
    }

}

Preferences Manager首选项管理器

@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")
}

} }

Favourite Language Adapter最喜欢的语言适配器

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

    }

}

Inside your PreferenceManager, try getting dataStore instance like this:在您的 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM