Yerel Ayarı programlı olarak ayarla


139

Uygulamam 3 (yakında 4) dili destekliyor. Birkaç yerel ayar oldukça benzer olduğu için kullanıcıya uygulamamda yerel ayarı değiştirme seçeneği sunmak istiyorum, örneğin bir İtalyan kişi İspanyolca'yı İngilizce yerine tercih edebilir.

Kullanıcının, uygulama için kullanılabilen yerel ayarlar arasından seçim yapmasının ve ardından kullanılan yerel ayarı değiştirmenin bir yolu var mı? Bir temel sınıfta gerçekleştirmek için basit bir görev olduğundan her Etkinlik için yerel ayar ayarlamak için bir sorun olarak görmüyorum.


Varsayılan yerel ayarı daha sonra geri yüklemek için bir yola ihtiyacınız varsa veya bir dil listesi içeren bir dil tercihine ihtiyacınız varsa ve yerel ayarı daha kolay değiştirmek istiyorsanız, bu yardımcı olabilir: github.com/delight-im/Android -Languages
gak

Yanıtlar:


114

configuration.localeAPI 24'ten kaldırıldığından bu yanıtı hala arayan kullanıcılar için artık şunları kullanabilirsiniz:

configuration.setLocale(locale);

Bu yöntem için minSkdVersion'ın API 17 olduğunu göz önünde bulundurun.

Tam örnek kod:

@SuppressWarnings("deprecation")
private void setLocale(Locale locale){
    SharedPrefUtils.saveLocale(locale); // optional - Helper method to save the selected language to SharedPreferences in case you might need to attach to activity context (you will need to code this)
    Resources resources = getResources();
    Configuration configuration = resources.getConfiguration();
    DisplayMetrics displayMetrics = resources.getDisplayMetrics();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1){
        configuration.setLocale(locale);
    } else{
        configuration.locale=locale;
    }
    if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N){
        getApplicationContext().createConfigurationContext(configuration);
    } else {
        resources.updateConfiguration(configuration,displayMetrics);
    }
}

Yerel ayarı çalışan bir Etkinlikle değiştirirseniz, değişikliklerin etkili olması için yeniden başlatmanız gerektiğini unutmayın.

11 MAYIS 2018'i DÜZENLE

@ CookieMonster'ın yayınından itibaren, daha yüksek API sürümlerinde yerel ayar değişikliği konusunda sorun yaşayabilirsiniz. Öyleyse, Temel Etkinliklerinize aşağıdaki kodu ekleyin, böylece her Etkinlik oluşturmadaki bağlam yerel ayarını güncelleyin:

@Override
protected void attachBaseContext(Context base) {
     super.attachBaseContext(updateBaseContextLocale(base));
}

private Context updateBaseContextLocale(Context context) {
    String language = SharedPrefUtils.getSavedLanguage(); // Helper method to get saved language from SharedPreferences
    Locale locale = new Locale(language);
    Locale.setDefault(locale);

    if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) {
        return updateResourcesLocale(context, locale);
    }

    return updateResourcesLocaleLegacy(context, locale);
}

@TargetApi(Build.VERSION_CODES.N_MR1)
private Context updateResourcesLocale(Context context, Locale locale) {
    Configuration configuration = new Configuration(context.getResources().getConfiguration())
    configuration.setLocale(locale);
    return context.createConfigurationContext(configuration);
}

@SuppressWarnings("deprecation")
private Context updateResourcesLocaleLegacy(Context context, Locale locale) {
    Resources resources = context.getResources();
    Configuration configuration = resources.getConfiguration();
    configuration.locale = locale;
    resources.updateConfiguration(configuration, resources.getDisplayMetrics());
    return context;
}

Bunu kullanırsanız, yerel ayarı ile ayarladığınızda dili SharedPreferences'a kaydetmeyi unutmayın. setLocate(locale)

7. NİSAN DÜZENLEME

Android 6 ve 7'de sorunlar yaşıyor olabilirsiniz ve bu, gece modunu kullanırken androidx kitaplıklarındaki bir sorun nedeniyle olur. Bunun için applyOverrideConfiguration, temel etkinliğinizde geçersiz kılmanız ve yeni bir yerel ayarın oluşturulması durumunda yapılandırmanın yerel ayarını güncellemeniz gerekir.

Basit kod:

@Override
public void applyOverrideConfiguration(Configuration overrideConfiguration) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && Build.VERSION.SDK_INT <= Build.VERSION_CODES.N_MR1) {
        // update overrideConfiguration with your locale  
        setLocale(overrideConfiguration) // you will need to implement this
    }
    super.applyOverrideConfiguration(overrideConfiguration);
} 

2
Bu etkinlikler için geçerlidir, ancak uygulama içeriğini güncellemenin bir yolu var mı?
alekop

2
Değiştirdikten sonra androidx.appcompat:appcompat:gelen versiyon 1.0.2için 1.1.0android 7 çalışmıyor ama android 9. çalışan
Bek

4
Ben ve 1.1.0androidx için aynı sorun
Alexander Dadukin

2
Benim için de aynı sorun. Androidx.appcompat olarak değiştirdikten sonra: appcompat: 1.1.0 'lib
Rahul Jidge

4
İle sorun ve içinde kod appcompat:1.1.0düzeltilebilirappcompat:1.2.0-alpha02Set<Locale> set = new LinkedHashSet<>(); // bring the target locale to the front of the list set.add(locale); LocaleList all = LocaleList.getDefault(); for (int i = 0; i < all.size(); i++) { // append other locales supported by the user set.add(all.get(i)); } Locale[] locales = set.toArray(new Locale[0]); configuration.setLocales(new LocaleList(locales));@TargetApi(Build.VERSION_CODES.N) updateResourcesLocale()
Vojtech Pohl

178

Umarım bu yardım (onResume içinde):

Locale locale = new Locale("ru");
Locale.setDefault(locale);
Configuration config = getBaseContext().getResources().getConfiguration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,
      getBaseContext().getResources().getDisplayMetrics());

2
Yani bu her aktivite için mi ayarlanmalıdır?
Tobias

6
1. getBaseContext () kullanmak zorunludur veya uygulama bağlamını kullanmak daha mı iyi olmalıdır? 2. her faaliyette bu kod çağrılmalıdır? Teşekkürler.
Paul

10
Bu kodu, başlatıcı Etkinliğimin (ve başka hiçbir yerde) onCreate () içine yerleştirdim ve yerel ayarın tüm uygulamaya uygulandığını görmek hoş bir sürpriz oldu. Bu 4.3 minSDK (ICS) ile 4.3 hedefleyen bir uygulamada.
IAmKale

8
Yeni bir Yapılandırma nesnesi oluşturmanıza gerek yoktur. Geçerli yapılandırmayı kullanabilir ve güncelleyebilirsiniz: getResources (). GetConfiguration ()
jmart

1
new Configuration (); kullanmayın, metin değiştirirGörünüm, fontSize
Jemshit Iskenderov

22

Android OS N ve sonraki sürümlere sahip cihazlarla yerel olarak programlı olarak ayarlamada bir sorun yaşadım . Benim için çözüm bu kodu temel faaliyetime yazıyordu:

(temel bir etkinliğiniz yoksa, bu değişiklikleri tüm etkinliklerinizde yapmanız gerekir)

@Override
protected void attachBaseContext(Context base) {
    super.attachBaseContext(updateBaseContextLocale(base));
}

private Context updateBaseContextLocale(Context context) {
    String language = SharedPref.getInstance().getSavedLanguage();
    Locale locale = new Locale(language);
    Locale.setDefault(locale);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        return updateResourcesLocale(context, locale);
    }

    return updateResourcesLocaleLegacy(context, locale);
}

@TargetApi(Build.VERSION_CODES.N)
private Context updateResourcesLocale(Context context, Locale locale) {
    Configuration configuration = context.getResources().getConfiguration();
    configuration.setLocale(locale);
    return context.createConfigurationContext(configuration);
}

@SuppressWarnings("deprecation")
private Context updateResourcesLocaleLegacy(Context context, Locale locale) {
    Resources resources = context.getResources();
    Configuration configuration = resources.getConfiguration();
    configuration.locale = locale;
    resources.updateConfiguration(configuration, resources.getDisplayMetrics());
    return context;
}

burada aramak için yeterli olmadığını unutmayın

createConfigurationContext(configuration)

ayrıca bu yöntemin döndürdüğü bağlamı almanız ve ardından bu bağlamı attachBaseContextyöntemde ayarlamanız gerekir .


Bu en kolay ve çalışan çözüm! Bu kabul edilen cevap olmalı.
Prasad Pawar

3
Bu kod büyük ölçüde 7'nin üstündeki androidde çalışır, ancak N'nin altındaki sürümlerde çalışmaz. Herhangi bir çözümünüz var mı?
Matin Ashtiani

Emin değilim çünkü benim için çalışıyor. Bir bakabilmem için bana uygulamanızı göndermek ister misiniz?
CookieMonster

2
Android N altındaki sürümlerde çalışmaz çünkü resources.updateConfiguration, attachBaseContext () yerine onCreate () öğesinde çağrılmalıdır
Chandler

@Chandler haklı. Android 6 için, ana / temel etkinliğinizin updateBaseContextLocaleyöntemini çağırın onCreate.
Azizjon Kholmatov

22

Bu sorunu çözmenin şu anki yolu için hiçbir cevap tamamlanmadığından, tam bir çözüm için talimat vermeye çalışıyorum. Bir şey eksikse veya daha iyi yapılabilirse lütfen yorum yapın.

Genel bilgi

İlk olarak, sorunu çözmek isteyen bazı kütüphaneler var, ancak hepsi eski görünüyor veya bazı özellikler eksik:

Ayrıca, bir kütüphane yazmak bu sorunu çözmek için iyi / kolay bir yol olmayabilir düşünüyorum çünkü yapılacak çok şey yok ve yapılması gereken tamamen ayrıştırılmış bir şey kullanmaktan ziyade mevcut kodu değiştirmektir. Bu nedenle, tamamlanması gereken aşağıdaki talimatları yazdım.

Çözümüm esas olarak https://github.com/gunhansancar/ChangeLanguageExample (zaten localhost ile bağlantılı olarak) üzerine kuruludur . Yöneltmek için bulduğum en iyi kod. Bazı açıklamalar:

  • Gerekirse, Android N (ve üstü) ve altı için yerel ayarları değiştirmek için farklı uygulamalar sağlar
  • Aşağıda gösterilen yaklaşımda gerekli olmayan updateViews()yerel ayarları (olağan yöntemi kullanarak getString(id)) değiştirdikten sonra tüm dizeleri manuel olarak güncellemek için her Etkinlikte bir yöntem kullanır.
  • Yalnızca dilleri destekler ve tam yerel ayarları (bölge (ülke) ve varyant kodlarını da içerir) içermez

Biraz değiştirdim, seçilen bölgeye devam eden kısmı ayırıyorum (aşağıda belirtildiği gibi bunu ayrı yapmak isteyebilirsiniz).

Çözüm

Çözüm aşağıdaki iki adımdan oluşur:

  • Uygulama tarafından kullanılacak yerel ayarı kalıcı olarak değiştirme
  • Uygulamanın yeniden başlatmadan özel yerel ayar kümesini kullanmasını sağlama

1. Adım: Yerel ayarı değiştirin

Gunhansancar'ın LocaleHelper'iLocaleHelper temel alan sınıfı kullanın :

  • Kullanılabilir dillerle ListPreferencea ekleyin PreferenceFragment(dillerin daha sonra eklenmesi gerektiğinde korunmalıdır)
import android.annotation.TargetApi;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build;
import android.preference.PreferenceManager;

import java.util.Locale;

import mypackage.SettingsFragment;

/**
 * Manages setting of the app's locale.
 */
public class LocaleHelper {

    public static Context onAttach(Context context) {
        String locale = getPersistedLocale(context);
        return setLocale(context, locale);
    }

    public static String getPersistedLocale(Context context) {
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
        return preferences.getString(SettingsFragment.KEY_PREF_LANGUAGE, "");
    }

    /**
     * Set the app's locale to the one specified by the given String.
     *
     * @param context
     * @param localeSpec a locale specification as used for Android resources (NOTE: does not
     *                   support country and variant codes so far); the special string "system" sets
     *                   the locale to the locale specified in system settings
     * @return
     */
    public static Context setLocale(Context context, String localeSpec) {
        Locale locale;
        if (localeSpec.equals("system")) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                locale = Resources.getSystem().getConfiguration().getLocales().get(0);
            } else {
                //noinspection deprecation
                locale = Resources.getSystem().getConfiguration().locale;
            }
        } else {
            locale = new Locale(localeSpec);
        }
        Locale.setDefault(locale);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            return updateResources(context, locale);
        } else {
            return updateResourcesLegacy(context, locale);
        }
    }

    @TargetApi(Build.VERSION_CODES.N)
    private static Context updateResources(Context context, Locale locale) {
        Configuration configuration = context.getResources().getConfiguration();
        configuration.setLocale(locale);
        configuration.setLayoutDirection(locale);

        return context.createConfigurationContext(configuration);
    }

    @SuppressWarnings("deprecation")
    private static Context updateResourcesLegacy(Context context, Locale locale) {
        Resources resources = context.getResources();

        Configuration configuration = resources.getConfiguration();
        configuration.locale = locale;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            configuration.setLayoutDirection(locale);
        }

        resources.updateConfiguration(configuration, resources.getDisplayMetrics());

        return context;
    }
}

SettingsFragmentAşağıdakine benzer bir oluşturun :

import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import mypackage.LocaleHelper;
import mypackage.R;

/**
 * Fragment containing the app's main settings.
 */
public class SettingsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
    public static final String KEY_PREF_LANGUAGE = "pref_key_language";

    public SettingsFragment() {
        // Required empty public constructor
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_settings, container, false);
        return view;
    }

    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
        switch (key) {
            case KEY_PREF_LANGUAGE:
                LocaleHelper.setLocale(getContext(), PreferenceManager.getDefaultSharedPreferences(getContext()).getString(key, ""));
                getActivity().recreate(); // necessary here because this Activity is currently running and thus a recreate() in onResume() would be too late
                break;
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        // documentation requires that a reference to the listener is kept as long as it may be called, which is the case as it can only be called from this Fragment
        getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
    }

    @Override
    public void onPause() {
        super.onPause();
        getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
    }
}

locales.xmlAşağıdaki şekilde kullanılabilir çevirileri olan tüm yerel ayarları listeleyen bir kaynak oluşturun (yerel ayar kodlarının listesi ):

<!-- Lists available locales used for setting the locale manually.
     For now only language codes (locale codes without country and variant) are supported.
     Has to be in sync with "settings_language_values" in strings.xml (the entries must correspond).
  -->
<resources>
    <string name="system_locale" translatable="false">system</string>
    <string name="default_locale" translatable="false"></string>
    <string-array name="locales">
        <item>@string/system_locale</item> <!-- system setting -->
        <item>@string/default_locale</item> <!-- default locale -->
        <item>de</item>
    </string-array>
</resources>

İçinde PreferenceScreen, kullanıcının kullanılabilir dilleri seçmesine izin vermek için aşağıdaki bölümü kullanabilirsiniz:

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <PreferenceCategory
        android:title="@string/preferences_category_general">
        <ListPreference
            android:key="pref_key_language"
            android:title="@string/preferences_language"
            android:dialogTitle="@string/preferences_language"
            android:entries="@array/settings_language_values"
            android:entryValues="@array/locales"
            android:defaultValue="@string/system_locale"
            android:summary="%s">
        </ListPreference>
    </PreferenceCategory>
</PreferenceScreen>

Aşağıdaki dizeleri hangi kullanır strings.xml:

<string name="preferences_category_general">General</string>
<string name="preferences_language">Language</string>
<!-- NOTE: Has to correspond to array "locales" in locales.xml (elements in same orderwith) -->
<string-array name="settings_language_values">
    <item>Default (System setting)</item>
    <item>English</item>
    <item>German</item>
</string-array>

2. Adım: Uygulamanın özel yerel ayarı kullanmasını sağlayın

Şimdi her bir Etkinliği özel yerel ayar kümesini kullanacak şekilde ayarlayın. Bunu gerçekleştirmek için en kolay yolu şu kodla tüm etkinlikler için ortak bir temel sınıf (önemli kodudur sahip olmaktır attachBaseContext(Context base)ve onResume()):

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;

import mypackage.LocaleHelper;
import mypackage.R;

/**
 * {@link AppCompatActivity} with main menu in the action bar. Automatically recreates
 * the activity when the locale has changed.
 */
public class MenuAppCompatActivity extends AppCompatActivity {
    private String initialLocale;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initialLocale = LocaleHelper.getPersistedLocale(this);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.menu_settings:
                Intent intent = new Intent(this, SettingsActivity.class);
                startActivity(intent);
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(LocaleHelper.onAttach(base));
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (initialLocale != null && !initialLocale.equals(LocaleHelper.getPersistedLocale(this))) {
            recreate();
        }
    }
}

Yaptığı şey

  • attachBaseContext(Context base)Önceden devam eden yerel ayarı kullanmak için geçersiz kılLocaleHelper
  • Yerel ayarda bir değişiklik tespit edin ve Dizeyi güncellemek için Etkinliği yeniden oluşturun

Bu çözüm hakkında notlar

  • Bir Etkinliğin yeniden oluşturulması, ActionBar'ın başlığını güncellemez (burada daha önce gözlemlendiği gibi: https://github.com/gunhansancar/ChangeLanguageExample/issues/1 ).

    • Bu sadece bir sahip olarak elde edilebilir setTitle(R.string.mytitle)içinde onCreate(), her bir faaliyet yöntemine.
  • Kullanıcının sistem varsayılan yerel ayarının yanı sıra uygulamanın varsayılan yerel ayarını (bu durumda "İngilizce" olarak adlandırılabilir) seçmesine olanak tanır.

  • Yalnızca dil kodları, bölge (ülke) ve varyant kodları (ör. fr-rCAŞimdiye kadar ) desteklenmemektedir. Tam yerel özellik özelliklerini desteklemek için Android Diller kitaplığındakine benzer bir ayrıştırıcı kullanılabilir (bölgeyi destekler, ancak varyant kodlarını içermez).

    • Birisi iyi bir ayrıştırıcı bulursa veya yazmışsa, çözümü ekleyebilmem için bir yorum ekleyin.

1
Mükemmel ama kabus kralı
Odys

1
Cehennem hayır, benim app zaten çok karmaşık, bu yaklaşım gelecekte korumak için bir kabus olacaktır.
Josh

@Josh Bunu biraz daha açıklayabilir misiniz? Aslında, kullandığınız her Etkinlik tabanı sınıfına yalnızca birkaç satır eklenmelidir. Tüm aktiviteler için aynı temel sınıfı kullanmanın mümkün olmayabileceğini görüyorum, ancak daha büyük projeler bile birkaçıyla başa çıkabilmelidir. Açı yönelimli programlama burada yardımcı olabilir, ancak kompozisyon (kodu ayrı bir sınıfa attachBaseContext(Context base)ve onResume()ayrı bir sınıfa taşı) hile yapabilir. Sonra tek yapmanız gereken her aktivite tabanı sınıfında bir nesne bildirmek ve bu iki çağrıyı devretmek.
user905686

Kullanıcı yerel ayarını değiştirirse, önceki tüm etkinlik sayfalarının yerel ayarı da değiştirilebilir mi?
Raju yourPepe

Bu konuda en iyi cevap bu. Teşekkürler kardeşim, işe yarıyor
Alok Gupta

16
@SuppressWarnings("deprecation")
public static void forceLocale(Context context, String localeCode) {
    String localeCodeLowerCase = localeCode.toLowerCase();

    Resources resources = context.getApplicationContext().getResources();
    Configuration overrideConfiguration = resources.getConfiguration();
    Locale overrideLocale = new Locale(localeCodeLowerCase);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        overrideConfiguration.setLocale(overrideLocale);
    } else {
        overrideConfiguration.locale = overrideLocale;
    }

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        context.getApplicationContext().createConfigurationContext(overrideConfiguration);
    } else {
        resources.updateConfiguration(overrideConfiguration, null);
    }
}

Belirli bir yerel ayarı zorlamak için bu yardımcı yöntemi kullanmanız yeterlidir.

UDPATE 22 AĞUSTOS 2017. Bu yaklaşımı daha iyi kullanın .


4

Aşağıdaki yöntemle bir yardımcı sınıf ekleyin:

public class LanguageHelper {
    public static final void setAppLocale(String language, Activity activity) {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            Resources resources = activity.getResources();
            Configuration configuration = resources.getConfiguration();
            configuration.setLocale(new Locale(language));
            activity.getApplicationContext().createConfigurationContext(configuration);
        } else {
            Locale locale = new Locale(language);
            Locale.setDefault(locale);
            Configuration config = activity.getResources().getConfiguration();
            config.locale = locale;
            activity.getResources().updateConfiguration(config,
                    activity.getResources().getDisplayMetrics());
        }

    }
}

Ve başlangıç ​​etkinliğinizde MainActivity.javaşöyle adlandırın:

public void onCreate(Bundle savedInstanceState) {
    ...
    LanguageHelper.setAppLocale("fa", this);
    ...
}

3

basit ve kolay

Locale locale = new Locale("en", "US");
Resources res = getResources();
DisplayMetrics dm = res.getDisplayMetrics();
Configuration conf = res.getConfiguration();
conf.locale = locale;
res.updateConfiguration(conf, dm);

burada "en" dil kodudur ve "US" ülke kodudur.


Yazımda belirtildiği gibi conf.locale=locale;kullanımdan kaldırıldı ve aynı zamanda updateConfiguration.
Ricardo

çok basit ve daha az karmaşık :)
Ramkesh Yadav

2

API16 - API28 için geçerlidir Bu yöntemi aşağıdaki noktalara yerleştirin:

    Context newContext = context;

        Locale locale = new Locale(languageCode);
        Locale.setDefault(locale);

        Resources resources = context.getResources();
        Configuration config = new Configuration(resources.getConfiguration());

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {

        config.setLocale(locale);
                newContext = context.createConfigurationContext(config);

        } else {

        config.locale = locale;
                resources.updateConfiguration(config, resources.getDisplayMetrics());
        }

    return newContext;
}

Bu kodu aşağıdakileri kullanarak tüm etkinliklerinize ekleyin:

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(localeUpdateResources(base, "<-- language code -->"));
    }

veya yeni bağlama ihtiyacınız olan parçalar, bağdaştırıcılar vb. için localeUpdateResources öğesini arayın.

Kredi: Yaroslav Berezanskyi


2

Süper basit bir yol var.

BaseActivity, Activity veya Fragment'ta attachBaseContext'i geçersiz kılma

 override fun attachBaseContext(context: Context) {
    super.attachBaseContext(context.changeLocale("tr"))
}

uzantı

fun Context.changeLocale(language:String): Context {
    val locale = Locale(language)
    Locale.setDefault(locale)
    val config = this.resources.configuration
    config.setLocale(locale)
    return createConfigurationContext(config)
}

2

Bulduğum androidx.appcompat:appcompat:1.1.0hata da basitçe arayarak sabitlenebilir getResources()içindeapplyOverrideConfiguration()

@Override public void
applyOverrideConfiguration(Configuration cfgOverride)
{
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP &&
      Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
    // add this to fix androidx.appcompat:appcompat 1.1.0 bug
    // which happens on Android 6.x ~ 7.x
    getResources();
  }

  super.applyOverrideConfiguration(cfgOverride);
}

1
 /**
 * Requests the system to update the list of system locales.
 * Note that the system looks halted for a while during the Locale migration,
 * so the caller need to take care of it.
 */
public static void updateLocales(LocaleList locales) {
    try {
        final IActivityManager am = ActivityManager.getService();
        final Configuration config = am.getConfiguration();

        config.setLocales(locales);
        config.userSetLocale = true;

        am.updatePersistentConfiguration(config);
    } catch (RemoteException e) {
        // Intentionally left blank
    }
}

1

Her şeyi deneyen ama çalışmayanlar için . Eğer ayarlarsanız olmadığını kontrol edin darkmodeile AppCompatDelegate.setDefaultNightModeve sistem daha sonra, karanlık değil Configuration.setLocaleyukarıdaki iş olmaz Andorid 7.0 .

Bu sorunu çözmek için her etkinliğinize bu kodu ekleyin:

override fun applyOverrideConfiguration(overrideConfiguration: Configuration?) {
  if (overrideConfiguration != null) {
    val uiMode = overrideConfiguration.uiMode
    overrideConfiguration.setTo(baseContext.resources.configuration)
    overrideConfiguration.uiMode = uiMode
  }
  super.applyOverrideConfiguration(overrideConfiguration)
}

-1

Bu kodu etkinliğinize ekleyin

 if (id==R.id.uz)
    {
        LocaleHelper.setLocale(MainActivity.this, mLanguageCode);

        //It is required to recreate the activity to reflect the change in UI.
        recreate();
        return true;
    }
    if (id == R.id.ru) {

        LocaleHelper.setLocale(MainActivity.this, mLanguageCode);

        //It is required to recreate the activity to reflect the change in UI.
        recreate();
    }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.