Это то, что я пробовал ---
Это класс хранения
Код: Выделить всё
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()))
}
}
Код: Выделить всё
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