Đặt ngôn ngữ lập trình


139

Ứng dụng của tôi hỗ trợ 3 (sớm 4) ngôn ngữ. Vì một số địa phương khá giống nhau, tôi muốn cung cấp cho người dùng tùy chọn thay đổi ngôn ngữ trong ứng dụng của tôi, ví dụ, một người Ý có thể thích tiếng Tây Ban Nha hơn tiếng Anh.

Có cách nào để người dùng chọn trong số các địa điểm có sẵn cho ứng dụng và sau đó thay đổi ngôn ngữ nào được sử dụng không? Tôi không coi đó là một vấn đề khi đặt ngôn ngữ cho mỗi Hoạt động vì đây là một nhiệm vụ đơn giản để thực hiện trong lớp cơ sở.


Nếu bạn cần một cách để khôi phục ngôn ngữ mặc định sau này hoặc nếu bạn cần một tùy chọn ngôn ngữ có chứa danh sách các ngôn ngữ và nếu bạn muốn thay đổi ngôn ngữ thuận tiện hơn, điều này có thể hữu ích: github.com/delight-im/Android
-Lôn

Câu trả lời:


114

Đối với những người vẫn đang tìm kiếm câu trả lời này, vì configuration.localekhông được dùng từ API 24, giờ đây bạn có thể sử dụng:

configuration.setLocale(locale);

Hãy xem xét rằng minSkdVersion cho phương pháp này là API 17.

Mã ví dụ đầy đủ:

@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);
    }
}

Đừng quên rằng, nếu bạn thay đổi ngôn ngữ với Hoạt động đang chạy, bạn sẽ cần khởi động lại nó để các thay đổi có hiệu lực.

EDIT ngày 11 tháng 5 năm 2018

Từ bài đăng của @ CookieMonster, bạn có thể gặp vấn đề trong việc giữ thay đổi ngôn ngữ trong các phiên bản API cao hơn. Nếu vậy, hãy thêm đoạn mã sau vào Hoạt động cơ sở của bạn để bạn cập nhật ngôn ngữ ngữ cảnh trên mỗi lần tạo Hoạt động:

@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;
}

Nếu bạn sử dụng điều này, đừng quên lưu ngôn ngữ vào SharedPreferences khi bạn đặt ngôn ngữ với setLocate(locale)

EDIT lần thứ 7 năm 2020

Bạn có thể gặp sự cố trong Android 6 và 7 và điều này xảy ra do sự cố trong thư viện androidx trong khi xử lý chế độ ban đêm. Đối với điều này, bạn cũng sẽ cần ghi đèapplyOverrideConfiguration trong hoạt động cơ sở của mình và cập nhật ngôn ngữ của cấu hình trong trường hợp một địa điểm mới được tạo.

Mã mẫu:

@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
Điều này hoạt động cho các hoạt động, nhưng có cách nào để cập nhật bối cảnh ứng dụng?
alekop

2
Sau khi thay đổi androidx.appcompat:appcompat:phiên bản từ 1.0.2để 1.1.0không làm việc trên android 7, nhưng làm việc trên android 9.
Bek

4
Vấn đề tương tự đối với tôi và 1.1.0androidx
Alexander Dadukin

2
Vấn đề tương tự đối với tôi. Sau khi tôi đổi thành androidx.appcompat: appcompat: 1.1.0 'lib
Rahul Jidge

4
Vấn đề với appcompat:1.1.0có thể được khắc phục với appcompat:1.2.0-alpha02và mã Set<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));bên trong@TargetApi(Build.VERSION_CODES.N) updateResourcesLocale()
Vojtech Pohl

178

Hy vọng sự giúp đỡ này (trong onResume):

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

2
Vì vậy, điều này phải được thiết lập cho mọi hoạt động?
Tobias

6
1. bắt buộc phải sử dụng getBaseContext () hoặc tốt hơn nên sử dụng bối cảnh ứng dụng? 2. mã này nên được gọi trong mỗi hoạt động? cảm ơn.
Paul

10
Tôi đã đặt mã này vào onCreate () của Activity launcher của tôi (và không ở đâu khác) và rất ngạc nhiên khi thấy rằng ngôn ngữ được áp dụng cho toàn bộ ứng dụng. Đây là trong một ứng dụng nhắm mục tiêu 4.3 với minSDK là 14 (ICS).
IAmKale

8
Không cần tạo đối tượng Cấu hình mới. Bạn có thể sử dụng cấu hình hiện tại và cập nhật nó: getResource (). GetConfiguration ()
jmart

1
không sử dụng Cấu hình mới ();, nó thay đổi văn bản Ứng dụng,
phông chữ Kích thước

22

Tôi gặp vấn đề với việc cài đặt ngôn ngữ lập trình với các thiết bị có HĐH Android N trở lên . Đối với tôi, giải pháp là viết mã này trong hoạt động cơ sở của tôi:

(nếu bạn không có hoạt động cơ bản thì bạn nên thực hiện những thay đổi này trong tất cả các hoạt động của mình)

@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;
}

lưu ý rằng ở đây không đủ để gọi

createConfigurationContext(configuration)

bạn cũng cần lấy bối cảnh mà phương thức này trả về và sau đó đặt bối cảnh này trong attachBaseContextphương thức.


Đây là giải pháp dễ dàng và hiệu quả nhất! Đây phải là câu trả lời được chấp nhận.
Prasad Pawar

3
Mã này hoạt động rất nhiều trên Android trên 7 nhưng trong các phiên bản dưới N không hoạt động. Bạn có giải pháp nào không?
Matin Ashtiani

Không chắc chắn vì nó đang làm việc cho tôi. Bạn có muốn gửi cho tôi thực hiện của bạn để tôi có thể xem?
CookieMonster

2
Không hoạt động trong các phiên bản trong Android N vì resource.updateConfiguration phải được gọi trong onCreate () thay vì Đính kèmBaseContext ()
Chandler

@Chandler nói đúng. Đối với Android 6-, hãy chỉnh updateBaseContextLocalephương thức trong onCreatehoạt động gốc / gốc của bạn.
Azizjon Kholmatov

22

Vì không có câu trả lời nào cho cách giải quyết vấn đề hiện tại, tôi cố gắng đưa ra hướng dẫn cho một giải pháp hoàn chỉnh. Hãy bình luận nếu thiếu một cái gì đó hoặc có thể được thực hiện tốt hơn.

Thông tin chung

Đầu tiên, tồn tại một số thư viện muốn giải quyết vấn đề nhưng tất cả chúng dường như đã lỗi thời hoặc thiếu một số tính năng:

Hơn nữa tôi nghĩ rằng viết thư viện có thể không phải là một cách tốt / dễ dàng để giải quyết vấn đề này bởi vì không có nhiều việc phải làm, và những gì phải làm là thay đổi mã hiện có hơn là sử dụng một cái gì đó hoàn toàn tách rời. Vì vậy, tôi đã soạn các hướng dẫn sau đây cần được hoàn thành.

Giải pháp của tôi chủ yếu dựa trên https://github.com/gunhansancar/ChangeL LanguageExample (như đã được liên kết bởi localhost ). Đó là mã tốt nhất tôi tìm thấy để định hướng tại. Một số nhận xét:

  • Khi cần thiết, nó cung cấp các triển khai khác nhau để thay đổi ngôn ngữ cho Android N (trở lên) trở xuống
  • Nó sử dụng một phương thức updateViews()trong mỗi Hoạt động để cập nhật thủ công tất cả các chuỗi sau khi thay đổi ngôn ngữ (sử dụng thông thường getString(id)) không cần thiết trong cách tiếp cận được hiển thị bên dưới
  • Nó chỉ hỗ trợ các ngôn ngữ và không hoàn thành các ngôn ngữ (bao gồm cả mã vùng (quốc gia) và mã biến thể)

Tôi đã thay đổi nó một chút, tách rời phần vẫn tồn tại miền địa phương đã chọn (như người ta có thể muốn làm điều đó một cách riêng biệt, như được đề xuất dưới đây).

Giải pháp

Giải pháp bao gồm hai bước sau:

  • Thay đổi vĩnh viễn ngôn ngữ được sử dụng bởi ứng dụng
  • Làm cho ứng dụng sử dụng bộ ngôn ngữ tùy chỉnh mà không cần khởi động lại

Bước 1: Thay đổi ngôn ngữ

Sử dụng lớp LocaleHelper, dựa trên LocaleHelper của gunhansancar :

  • Thêm một ListPreferencetrong một PreferenceFragmentvới các ngôn ngữ có sẵn (phải được duy trì khi ngôn ngữ nên được thêm vào sau)
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;
    }
}

Tạo một cái SettingsFragmentnhư sau:

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);
    }
}

Tạo tài nguyên locales.xmlliệt kê tất cả các địa điểm với các bản dịch có sẵn theo cách sau ( danh sách mã địa phương ):

<!-- 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>

Trong phần của PreferenceScreenbạn, bạn có thể sử dụng phần sau để cho phép người dùng chọn ngôn ngữ có sẵn:

<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>

trong đó sử dụng các chuỗi sau từ 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>

Bước 2: Làm cho ứng dụng sử dụng ngôn ngữ tùy chỉnh

Bây giờ hãy thiết lập từng Hoạt động để sử dụng bộ ngôn ngữ tùy chỉnh. Cách dễ nhất để thực hiện điều này là có một lớp cơ sở chung cho tất cả các hoạt động với mã sau (nơi chứa mã quan trọng attachBaseContext(Context base)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();
        }
    }
}

Những gì nó làm là

  • Ghi đè attachBaseContext(Context base)để sử dụng ngôn ngữ đã tồn tại trước đó vớiLocaleHelper
  • Phát hiện thay đổi ngôn ngữ và tạo lại Activity để cập nhật chuỗi của nó

Ghi chú về giải pháp này

  • Tái tạo một Hoạt động không cập nhật tiêu đề của ActionBar (như đã thấy ở đây: https://github.com/gunhansancar/ChangeL LanguageExample /issues / 1 ).

    • Điều này có thể đạt được bằng cách đơn giản là có một setTitle(R.string.mytitle)trong các onCreate()phương pháp của từng hoạt động.
  • Nó cho phép người dùng chọn ngôn ngữ mặc định của hệ thống, cũng như miền địa phương mặc định của ứng dụng (có thể được đặt tên, trong trường hợp này là "Tiếng Anh").

  • Chỉ có mã ngôn ngữ, không có vùng (quốc gia) và mã biến thể (như fr-rCA) được hỗ trợ cho đến nay. Để hỗ trợ các đặc tả địa phương đầy đủ, có thể sử dụng trình phân tích cú pháp tương tự như trong thư viện Ngôn ngữ Android (hỗ trợ vùng nhưng không có mã biến thể).

    • Nếu ai đó tìm thấy hoặc đã viết một trình phân tích cú pháp tốt, hãy thêm một nhận xét để tôi có thể đưa nó vào giải pháp.

1
Tuyệt vời nhưng là vua của cơn ác mộng
Odys

1
Chết tiệt, ứng dụng của tôi quá phức tạp rồi, cách tiếp cận này sẽ là một cơn ác mộng cần duy trì trong tương lai.
Josh

@Josh Bạn có thể giải thích điều này hơn một chút? Thực tế chỉ có một vài dòng phải được thêm vào mỗi lớp cơ sở Activity mà bạn sử dụng. Tôi thấy rằng có thể không thể sử dụng cùng một lớp cơ sở cho tất cả các hoạt động nhưng ngay cả các dự án lớn hơn cũng có thể hòa hợp với một số ít. Lập trình hướng theo khía cạnh có thể giúp đỡ ở đây nhưng thành phần (di chuyển mã từ attachBaseContext(Context base)onResume()sang một lớp riêng biệt) có thể thực hiện thủ thuật. Sau đó, tất cả những gì bạn phải làm là khai báo một đối tượng trong mỗi lớp cơ sở hoạt động và ủy thác hai cuộc gọi đó.
dùng905686

Nếu người dùng thay đổi ngôn ngữ, địa điểm của tất cả các trang hoạt động trước đó cũng có thể được thay đổi?
Raju yourPepe

Đây là câu trả lời tốt nhất về vấn đề này. Cảm ơn người anh em, nó hoạt động
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);
    }
}

Chỉ cần sử dụng phương pháp trợ giúp này để buộc miền địa phương cụ thể.

UDPATE 22 AUG 2017. Sử dụng tốt hơn phương pháp này .


4

Thêm một lớp trợ giúp với phương thức sau:

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());
        }

    }
}

Và gọi nó trong hoạt động khởi nghiệp của bạn, như MainActivity.java:

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

3

đơn giản và dễ dàng

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

trong đó "en" là mã ngôn ngữ và "US" là mã quốc gia.


Như đã nêu trong bài viết của tôi conf.locale=locale;không được dùng nữa, và cũng vậy updateConfiguration.
Ricardo

rất đơn giản và ít phức tạp :)
Ramkesh Yadav

2

Hợp lệ cho API16 đến API28 Chỉ cần đặt phương thức này một số trong đó:

    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;
}

Chèn mã này vào tất cả các hoạt động của bạn bằng cách sử dụng:

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

hoặc gọi localeUpdateResource trên các đoạn, bộ điều hợp, v.v. nơi bạn cần bối cảnh mới.

Tín dụng: Yar Tư Berezanskyi


2

Có một cách siêu đơn giản.

trong BaseActivity, Activity hoặc Fragment ghi đè Đính kèmBaseContext

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

sự mở rộng

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

Tôi tìm thấy androidx.appcompat:appcompat:1.1.0lỗi cũng có thể được cố định bằng cách đơn giản gọi getResources()trongapplyOverrideConfiguration()

@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

Đối với những người đã thử mọi thứ nhưng không làm việc . Vui lòng kiểm tra rằng nếu bạn đặt darkmodevới AppCompatDelegate.setDefaultNightModehệ thống không phải là bóng tối, sau đó Configuration.setLocalesẽ không làm việc trên Andorid 7.0 .

Thêm mã này vào mọi hoạt động của bạn để giải quyết vấn đề này:

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

-1

Đặt mã này vào hoạt động của bạn

 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();
    }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.