Перевод пользовательского интерфейса android (в Kotlin) - PullRequest
0 голосов
/ 13 января 2020

Мне нужно перевести мой интерфейс, используя Kotlin (для Android). Я использовал этот код (каждый раз, когда пользователи запускают приложение):

    val sharedPref: SharedPreferences = getSharedPreferences(UI_LANGUAGE_CHANGED, PRIVATE_MODE)
    var restart: Boolean = sharedPref.getBoolean(UI_LANGUAGE_CHANGED, true)

    var lang = selectedLanguageVar.split("-")[0]
    if (translations_languages.indexOf(lang) == -1) {
        lang = "en"
    }
    //println("-->sel: " + selectedLanguageVar + " -->lang: " + getString(R.string.language))
    //println("-->index: " + translations_languages.indexOf(lang))
    var locale: Locale = Locale(lang)
    Locale.setDefault(locale)
    var res: Resources = resources
    var config: Configuration = res.configuration
    config.setLocale(locale)
    //config.setLayoutDirection(locale)
    //createConfigurationContext(config)
    resources.updateConfiguration(config, resources.displayMetrics)

    if (restart || type == "restart") {
        val intent = Intent(this, RestartActivity::class.java).also {
            startActivity(it)

            finish()
        }
    } else {
        if (type == "start") {
            val intent = Intent(this, RestartActivity::class.java).also {
                startActivity(it)
            }
        }
    }

, но он переводится на выбранный язык ПРОСТО, когда это язык устройства, когда я устанавливал приложение. Так, например, я устанавливаю приложение и на моем устройстве есть Engli sh и французский. Если я выберу один из этих двух языков, он будет переведен правильно, в противном случае он не будет работать.

Я пробовал также createConfigurationContext(config), но он не работает. Есть ли способ всегда переводить на выбранный язык (независимо от устройства)?

1 Ответ

1 голос
/ 13 января 2020

Как указано в комментариях, изменение языка зависит от уровня API, который вы поддерживаете. Вот как мы это делаем в моей компании, которая поддерживает также начиная с API 23.

Мы делаем это, оборачивая контекст единственного действия, которое мы имеем. Здесь я перехожу на французский, но вам нужно решить, какой язык использовать. Я думаю, что эта часть зависит от вашего варианта использования, поэтому я опущу это из этого ответа. Каждый раз, когда вы хотите изменить язык, вам нужно воссоздать игру. Это легко сделать, получив экземпляр действия и выполнив на нем recreate().

class BaseActivity : AppCompatActivity() {

  override fun attachBaseContext(newBase: Context) {
    super.attachBaseContext(newBase.wrap(Locale.FRENCH))
  }
}

Метод, который оборачивает контекст, представляет собой функцию расширения, написанную как:

fun Context.wrap(desiredLocale: Locale): Context {
  if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M)
    return getUpdatedContextApi23(desiredLocale)

  return if (Build.VERSION.SDK_INT == Build.VERSION_CODES.N) 
      getUpdatedContextApi24(desiredLocale) 
    else 
      getUpdatedContextApi25(desiredLocale)
}

А вот каждый из методов, которые обновляют локаль в зависимости от версии:

@TargetApi(Build.VERSION_CODES.M)
private fun Context.getUpdatedContextApi23(locale: Locale): Context {
  val configuration = resources.configuration
  configuration.locale = locale
  return createConfigurationContext(configuration)
}

private fun Context.getUpdatedContextApi24(locale: Locale): Context {
  val configuration = resources.configuration
  configuration.setLocale(locale)
  return createConfigurationContext(configuration)
}

@TargetApi(Build.VERSION_CODES.N_MR1)
private fun Context.getUpdatedContextApi25(locale: Locale): Context {
  val localeList = LocaleList(locale)
  val configuration = resources.configuration
  configuration.locales = localeList
  return createConfigurationContext(configuration)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...