Как изменить языковые настройки всего приложения одновременно во время выполнения, Android KotlinAndroid

Форум для тех, кто программирует под Android
Ответить Пред. темаСлед. тема
Гость
 Как изменить языковые настройки всего приложения одновременно во время выполнения, Android Kotlin

Сообщение Гость »

У меня есть приложение для Android на Kotlin, в котором я выполняю несколько действий. Я хочу изменить язык во время выполнения.
Это то, что я пробовал ---
Это класс хранения

Код: Выделить всё

class Storage(context: Context) {
private var preferences: SharedPreferences = context.getSharedPreferences(Helper.PREF_SETTINGS, Context.MODE_PRIVATE)

fun getPreferredLocale(): String {
Log.d("CheckLanguageLocale", "getPreferredLocale: --${preferences.getString("preferred_locale", LocaleUtil.OPTION_PHONE_LANGUAGE)!!}")
return preferences.getString("preferred_locale", LocaleUtil.OPTION_PHONE_LANGUAGE)!!
}

fun setPreferredLocale(localeCode: String) {
preferences.edit().putString("preferred_locale", localeCode).apply()
}
}
Это класс приложений

Код: Выделить всё

class MyApp: Application() {
val storage : Storage by lazy {
Storage(this)
}

override fun attachBaseContext(base: Context) {
Log.d("CheckLanguageLocale", "attach base context get call")

super.attachBaseContext(LocaleUtil.getLocalizedContext(base, Storage(base).getPreferredLocale()))
}
}
Это класс localeUtil

Код: Выделить всё

class LocaleUtil {
companion object {
val supportedLocales = listOf("en", "bn")
const val OPTION_PHONE_LANGUAGE = "sys_def"

/**
* returns the locale to use depending on the preference value
* when preference value = "sys_def" returns the locale of current system
* else it returns the locale code e.g.  "en", "bn"  etc.
*/
fun getLocaleFromPrefCode(prefCode: String): Locale {
val localeCode = if(prefCode != OPTION_PHONE_LANGUAGE) {
prefCode
} else {
val systemLang = ConfigurationCompat.getLocales(Resources.getSystem().configuration).get(0)!!.language
if(systemLang in supportedLocales){
systemLang
} else {
"en"
}
}
return Locale(localeCode)
}

fun getLocalizedConfiguration(prefLocaleCode: String): Configuration {
val locale = getLocaleFromPrefCode(prefLocaleCode)
return getLocalizedConfiguration(locale)
}

fun getLocalizedConfiguration(locale: Locale): Configuration {
val config = Configuration()
return config.apply {
config.setLayoutDirection(locale)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
config.setLocale(locale)
val localeList = LocaleList(locale)
LocaleList.setDefault(localeList)
config.setLocales(localeList)
} else {
config.setLocale(locale)
}
}
}

fun getLocalizedContext(baseContext: Context, prefLocaleCode: String): Context {
val currentLocale = getLocaleFromPrefCode(prefLocaleCode)

val baseLocale = getLocaleFromConfiguration(baseContext.resources.configuration)
Locale.setDefault(currentLocale)
return if (!baseLocale.toString().equals(currentLocale.toString(), ignoreCase = true)) {
val config = getLocalizedConfiguration(currentLocale)
baseContext.createConfigurationContext(config)
} else {
baseContext
}
}
fun applyLocalizedContext(baseContext: Context, prefLocaleCode: String) {
val currentLocale = getLocaleFromPrefCode(prefLocaleCode)
Log.d("CheckLanguageLocale", "currentLocale on applyLocalizedContext --$currentLocale")
val baseLocale = getLocaleFromConfiguration(baseContext.resources.configuration)
Log.d("CheckLanguageLocale", "baseLocale on applyLocalizedContext --$baseLocale")
Locale.setDefault(currentLocale)
if (!baseLocale.toString().equals(currentLocale.toString(), ignoreCase = true)) {
val config = getLocalizedConfiguration(currentLocale)
Log.d("CheckLanguageLocale", "config --$config")
baseContext.resources.updateConfiguration(config, baseContext.resources.displayMetrics)
}
}

@Suppress("DEPRECATION")
private fun getLocaleFromConfiguration(configuration: Configuration): Locale {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
configuration.locales.get(0)
} else {
configuration.locale
}
}

fun getLocalizedResources(resources: Resources, prefLocaleCode: String): Resources {
val locale = getLocaleFromPrefCode(prefLocaleCode)
val config = resources.configuration
@Suppress("DEPRECATION")
config.locale = locale
config.setLayoutDirection(locale)

@Suppress("DEPRECATION")
resources.updateConfiguration(config, resources.displayMetrics)
return resources
}
}
}
Это код действия, в котором я меняю язык

Код: Выделить всё

class ChangeAppLanguageActivity : BaseActivity() {
lateinit var binding: ActivityChangeAppLanguageBinding
private lateinit var firstLocaleCode: String
private lateinit var secondLocaleCode: String
private lateinit var currentSystemLocaleCode: String
override fun onCreate(savedInstanceState:  Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityChangeAppLanguageBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.toolbar.backBtn.setOnClickListener {
navigation()
}
binding.toolbar.userProfilePhoto.setOnClickListener {
goToAccount(this)
}
setProfile(this, binding.toolbar.userProfilePhoto)
/*  binding.rlEnglish.setOnClickListener {

startActivity( Intent(this, AccountScreen::class.java))
}*/
currentSystemLocaleCode = ConfigurationCompat.getLocales(Resources.getSystem().configuration).get(0)!!.language
if(storage.getPreferredLocale() == LocaleUtil.OPTION_PHONE_LANGUAGE){
if(currentSystemLocaleCode in LocaleUtil.supportedLocales){
binding.tvAppLocale.text = getString(R.string.phone_language, Locale(currentSystemLocaleCode).displayLanguage)
} else {
//current system language is neither English nor my second language (for me Bangla)
binding.tvAppLocale.text = "English"
}
} else {
if(currentSystemLocaleCode == storage.getPreferredLocale()){
binding.tvAppLocale.text = getString(R.string.phone_language, Locale(currentSystemLocaleCode).displayLanguage)
} else {
binding.tvAppLocale.text = Locale(storage.getPreferredLocale()).displayLanguage
}
}
firstLocaleCode = if(currentSystemLocaleCode in LocaleUtil.supportedLocales){
currentSystemLocaleCode
} else {
if(storage.getPreferredLocale() == LocaleUtil.OPTION_PHONE_LANGUAGE){
//current system language is neither English nor my second language (for me Bangla)
"en"
} else {
storage.getPreferredLocale()
}
}
secondLocaleCode = getSecondLanguageCode()
initRadioButtonUI()
binding.radioGroup.setOnCheckedChangeListener { _, checkedId ->
when (checkedId) {
R.id.op1 -> {
updateAppLocale(LocaleUtil.OPTION_PHONE_LANGUAGE)

//recreate()
startActivity(Intent(this,AccountScreen::class.java))
}
R.id.op2 -> {
updateAppLocale(secondLocaleCode)
//recreate()
startActivity(Intent(this,AccountScreen::class.java))
}
}
}
}

private fun getSecondLanguageCode(): String {
return if(firstLocaleCode == "en") "bn"  else "en"
}

private fun initRadioButtonUI() {
if(currentSystemLocaleCode in LocaleUtil.supportedLocales){
binding.op1.text = getString(R.string.phone_language, getLanguageNameByCode(firstLocaleCode))
} else {
binding.op1.text = getLanguageNameByCode(firstLocaleCode)
}
binding.op2.text = getLanguageNameByCode(secondLocaleCode)
if(storage.getPreferredLocale() == secondLocaleCode)  binding.op2.isChecked = true
else  binding.op1.isChecked = true
}

private fun getLanguageNameByCode(code: String) : String{
val tempLocale = Locale(code)
return tempLocale.getDisplayLanguage(tempLocale)
}

private fun updateAppLocale(locale: String) {
Log.d("CheckLanguageLocale", "onCreate: update locale call with--$locale")
storage.setPreferredLocale(locale)
LocaleUtil.applyLocalizedContext(applicationContext, locale)
}
}
и вот что я сделал с базовой активностью

Код: Выделить всё

 private lateinit var oldPrefLocaleCode : String
protected val storage : Storage by lazy {
(application as MyApp).storage
}
private fun resetTitle() {
try {
val label = packageManager.getActivityInfo(componentName, PackageManager.GET_META_DATA).labelRes;
if (label != 0) {
setTitle(label);
}
} catch (e: PackageManager.NameNotFoundException) {}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
resetTitle()
}
override fun attachBaseContext(newBase: Context) {
Log.d("CheckLanguageLocale", "attach base context get call from base activity")
oldPrefLocaleCode = Storage(newBase).getPreferredLocale()
applyOverrideConfiguration(LocaleUtil.getLocalizedConfiguration(oldPrefLocaleCode))
super.attachBaseContext(newBase)
}
override fun onResume() {
val currentLocaleCode = Storage(this).getPreferredLocale()
if(oldPrefLocaleCode != currentLocaleCode){
//recreate() //locale is changed, restart the activty to update
oldPrefLocaleCode = currentLocaleCode
}
super.onResume()
}
Теперь основная проблема заключается в том, что всякий раз, когда я меняю язык, ресурсы не меняются, например, если язык изменен на бенгальский, не изменяются, но код локали обновляется. И, во-вторых, если я вызову воссоздание, приложение выйдет из строя.

Подробнее здесь: https://stackoverflow.com/questions/782 ... roid-kotli
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Android»