0

我有 2 个主要字符串文件的副本 - 俄语和英语本地化。我想通过在 Fragment 的弹出菜单中切换它们来更改应用程序语言。该菜单确实已经更改了 dataStore 中的“NativeLanguage”变量,它决定了我的应用程序中的几件事,包括 UI 语言(但不仅限于)。

谁能给我一些建议如何将所选的本地化数据保存在 dataStore 中并根据此存储的数据设置所有 UI 文本?感谢任何帮助

在片段中:

@AndroidEntryPoint
class SettingsFragment : Fragment(R.layout.settings_layout), PopupMenu.OnMenuItemClickListener {

    private val viewModel: SettingsViewModel by viewModels()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        val binding = SettingsLayoutBinding.bind(view)
        binding.apply {
            viewModel.readNatLang.observe(viewLifecycleOwner) {
                languageButton.text = if (it == NativeLanguage.RUS) "Русский" else "English"
                languageButton.setOnClickListener { showPopup(languageButton) }
            }
        }
        setHasOptionsMenu(true)
    }

    fun showPopup(v: View) {
        val popup = PopupMenu(requireContext(), v)
        popup.setOnMenuItemClickListener(this)
        popup.inflate(R.menu.language_menu)
        popup.show()
    }

    override fun onMenuItemClick(item: MenuItem): Boolean {
        return when(item.itemId) {
            R.id.item_ru -> {
                viewModel.saveNatLang(NativeLanguage.RUS)
                true
            }
            R.id.item_en -> {
                viewModel.saveNatLang(NativeLanguage.ENG)
                true
            }
            else -> false
        }
    }
}

在视图模型中:

class SettingsViewModel @ViewModelInject constructor(
    private val preferencesManager: PreferencesManager
    ) : ViewModel() {

    private val natLangFlow = preferencesManager.nativeLanguageFlow
    val readNatLang = natLangFlow.asLiveData()

    fun saveNatLang(nativeLanguage: NativeLanguage) = viewModelScope.launch {
        preferencesManager.updateNativeLanguage(nativeLanguage)
    }
}

在数据存储中:

enum class NativeLanguage { RUS, ENG }

@Singleton
class PreferencesManager @Inject constructor(@ApplicationContext context: Context) {

    private val dataStore = context.createDataStore("user_preferences")

    val nativeLanguageFlow = dataStore.data
        .catch { exception ->
            if (exception is IOException) {
                Log.e(TAG, "Error reading preferences", exception)
                emit(emptyPreferences())
            } else {
                throw exception
            }
        }
        .map { preferences ->
            val nativeLanguage = NativeLanguage.valueOf(
                preferences[PreferencesKeys.NATIVE_LANGUAGE] ?: NativeLanguage.RUS.name
            )
            nativeLanguage
        }

    suspend fun updateNativeLanguage(nativeLanguage: NativeLanguage) {
        dataStore.edit { preferences ->
            preferences[PreferencesKeys.NATIVE_LANGUAGE] = nativeLanguage.name
        }
    }

    private object PreferencesKeys {
        val NATIVE_LANGUAGE = preferencesKey<String>("native_language")
    }

}
4

0 回答 0