簡體   English   中英

嘗試從首選項數據存儲中讀取數據時返回 null

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM