Android 如何使存储在数据存储中的值影响应用程序的当前语言?
我有两份主字符串文件-俄语和英语本地化。我想通过在片段中的弹出菜单中切换它们来更改应用程序语言。菜单已经改变了数据存储中的“NativeLanguage”变量,它决定了我的应用程序中的一些事情,包括UI语言(但不仅仅是) 有谁能给我一些建议,如何将选定的本地化数据保存在数据存储中,并根据存储的数据设置所有UI文本?谢谢你的帮助 片段: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
@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”)
}
}