Android 如何使存储在数据存储中的值影响应用程序的当前语言?

Android 如何使存储在数据存储中的值影响应用程序的当前语言?,android,kotlin,localization,runtime,android-jetpack-datastore,Android,Kotlin,Localization,Runtime,Android Jetpack Datastore,我有两份主字符串文件-俄语和英语本地化。我想通过在片段中的弹出菜单中切换它们来更改应用程序语言。菜单已经改变了数据存储中的“NativeLanguage”变量,它决定了我的应用程序中的一些事情,包括UI语言(但不仅仅是) 有谁能给我一些建议,如何将选定的本地化数据保存在数据存储中,并根据存储的数据设置所有UI文本?谢谢你的帮助 片段: @AndroidEntryPoint class SettingsFragment : Fragment(R.layout.settings_layout), P

我有两份主字符串文件-俄语和英语本地化。我想通过在片段中的弹出菜单中切换它们来更改应用程序语言。菜单已经改变了数据存储中的“NativeLanguage”变量,它决定了我的应用程序中的一些事情,包括UI语言(但不仅仅是)

有谁能给我一些建议,如何将选定的本地化数据保存在数据存储中,并根据存储的数据设置所有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
        }
    }
}
在ViewModel中:

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

}
enum类本地语言{RUS,ENG}
@独生子女
类首选项管理器@injectconstructor(@ApplicationContext:context){
private val dataStore=context.createDataStore(“用户首选项”)
val nativeLanguageFlow=dataStore.data
.catch{异常->
if(异常为IOException){
Log.e(标记“错误读取首选项”,异常)
emit(emptyPreferences())
}否则{
抛出异常
}
}
.map{首选项->
val nativeLanguage=nativeLanguage.valueOf(
首选项[首选项skeys.NATIVE_LANGUAGE]?:NativeLanguage.RUS.name
)
母语
}
挂起趣味更新活动语言(nativeLanguage:nativeLanguage){
dataStore.edit{首选项->
首选项[首选项skeys.NATIVE_LANGUAGE]=nativeLanguage.name
}
}
私有对象优先权{
val NATIVE_LANGUAGE=首选项skey(“NATIVE_LANGUAGE”)
}
}