Làm cách nào để thay đổi ngôn ngữ của ứng dụng khi người dùng chọn ngôn ngữ?


106

Tôi muốn ứng dụng của mình hỗ trợ ba ngôn ngữ Tây Ban Nha, Bồ Đào Nha và tiếng Anh. Và cung cấp tùy chọn để chọn ngôn ngữ trong ứng dụng, tôi đã thực hiện

1) 3 thư mục có thể vẽ drawable-es, drawable-pt, drawable.

2) 3 giá trị thư mục giá trị-es, giá trị-pt, giá trị. Thay đổi giá trị String.xml theo ngôn ngữ.

Tôi có imageView để chọn ngôn ngữ. Khi nhấp vào nó, menu sẽ mở ra bao gồm tùy chọn tiếng Anh, tiếng Tây Ban Nha, tiếng Bồ Đào Nha.

Tôi đặt Ngôn ngữ bên trong ứng dụng trên lựa chọn tùy chọn bằng mã này

public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.en:
             Locale locale = new Locale("en"); 
             Locale.setDefault(locale);
             Configuration config = new Configuration();
             config.locale = locale;
             getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
             Toast.makeText(this, "Locale in English !", Toast.LENGTH_LONG).show();
             break;

        case R.id.pt:
             Locale locale2 = new Locale("pt"); 
             Locale.setDefault(locale2);
             Configuration config2 = new Configuration();
             config2.locale = locale2;
             getBaseContext().getResources().updateConfiguration(config2, getBaseContext().getResources().getDisplayMetrics());

             Toast.makeText(this, "Locale in Portugal !", Toast.LENGTH_LONG).show();
             break;

        case R.id.es:
             Locale locale3 = new Locale("es"); 
             Locale.setDefault(locale3);
             Configuration config3 = new Configuration();
             config3.locale = locale3;
             getBaseContext().getResources().updateConfiguration(config3, getBaseContext().getResources().getDisplayMetrics());

             Toast.makeText(this, "Locale in Spain !", Toast.LENGTH_LONG).show();
             break;     
    }
    return super.onOptionsItemSelected(item);
}

Tôi đã khai báo trong Manifest- android: configChanges = "locale"

Nó hoạt động nhưng nó có một số vấn đề.

Vấn đề:-

1) Khi ngôn ngữ được chọn, màn hình bao gồm hình ảnh lựa chọn ngôn ngữ không thay đổi nhưng các màn hình khác sẽ thay đổi.

2) Sau khi thay đổi hướng ứng dụng khôi phục ngôn ngữ theo ngôn ngữ của điện thoại.


1
Đối với vấn đề thứ 2 thử thêm: android:configChanges="locale"cho hoạt động của bạn bên trong AndroidManifest.xml
Parth Doshi

tôi đã thêm mọi hoạt động trong bản kê khai của mình.
mukesh 16/10/12

Bạn có thể sử dụng thư viện sau đây, cung cấp danh sách ngôn ngữ, ưu tiên cho màn hình cài đặt của bạn, và ghi đè ngôn ngữ trong ứng dụng của bạn: github.com/delight-im/Android-Languages
caw

Câu trả lời:


172

Đây là đoạn trích cho trang web: http://android.programmerguru.com/android-localization-at-runtime/

Thật đơn giản để thay đổi ngôn ngữ của ứng dụng khi người dùng chọn nó từ danh sách các ngôn ngữ. Có một phương thức như bên dưới chấp nhận ngôn ngữ là Chuỗi (như 'en' đối với tiếng Anh, 'hi' đối với tiếng Hin-ddi), định cấu hình ngôn ngữ cho Ứng dụng của bạn và làm mới hoạt động hiện tại của bạn để phản ánh sự thay đổi trong ngôn ngữ. Ngôn ngữ bạn đã áp dụng sẽ không được thay đổi cho đến khi bạn thay đổi lại theo cách thủ công.

public void setLocale(String lang) { 
    Locale myLocale = new Locale(lang); 
    Resources res = getResources(); 
    DisplayMetrics dm = res.getDisplayMetrics(); 
    Configuration conf = res.getConfiguration(); 
    conf.locale = myLocale; 
    res.updateConfiguration(conf, dm); 
    Intent refresh = new Intent(this, AndroidLocalize.class); 
    finish();
    startActivity(refresh); 
} 

Đảm bảo bạn đã nhập các gói sau:

import java.util.Locale; 
import android.os.Bundle; 
import android.app.Activity; 
import android.content.Intent; 
import android.content.res.Configuration; 
import android.content.res.Resources; 
import android.util.DisplayMetrics; 

thêm tệp kê khai vào hoạt động android: configChanges = "locale | orient"


2
Ừ chắc chắn. Tôi có thể cung cấp phần trích dẫn của trang web. Tôi cần cung cấp ở đâu vui lòng cho tôi biết. Cảm ơn.
Udhay

3
Đảm bảo thêm finish () để bạn không có hai bản sao hoạt động của mình trong ngăn xếp điều hướng.
Joel Teply

6
finish()cần được gọi trước startActivity(refresh). Nếu không, Ứng dụng có thể thoát thay vì Hoạt động được khởi động lại.
Mohammed Ali

10
Hi, tôi đã làm điều đó, nó hoạt động, nhưng khi tôi khởi động lại ứng dụng, nó sẽ trả về ngôn ngữ mặc định ..
Sofiane Hassaini

5
Cấu hình cấu hình = Cấu hình mới (newConfig); config.locale = locale; Trong trường hợp của tôi nhận được tin nhắn này. ngôn ngữ không được dùng nữa trong API cấp 25
Milon

9

Các giải pháp tốt được giải thích khá tốt ở đây. Nhưng đây là một nữa.

Tạo CustomContextWrapperlớp mở rộng của riêng bạn ContextWrappervà sử dụng nó để thay đổi cài đặt Ngôn ngữ cho ứng dụng hoàn chỉnh. Đây là GIST với cách sử dụng.

Và sau đó gọi CustomContextWrappervới số nhận dạng ngôn ngữ đã lưu, ví dụ 'hi'cho ngôn ngữ Hindi trong phương thức vòng đời hoạt động attachBaseContext. Cách sử dụng ở đây:

@Override
protected void attachBaseContext(Context newBase) {
    // fetch from shared preference also save the same when applying. Default here is en = English
    String language = MyPreferenceUtil.getInstance().getString("saved_locale", "en");
    super.attachBaseContext(MyContextWrapper.wrap(newBase, language));
}

Cảm ơn bạn đã liên kết nó đang làm việc nhưng tôi không hiểu một vài điều, tôi chỉ gọi là MyContextWrapper.warptrong onAttachchỉ một mảnh của ứng dụng của tôi, nhưng ngôn ngữ được thay đổi cho toàn bộ ứng dụng, nhưng các chức danh hoạt động không bị thay đổi, tôi nghĩ rằng nó là do tiêu đề tệp kê khai được ưu tiên hơn, nhưng nếu tôi gọi cùng một phương thức trong onAttachBaseContexlớp ứng dụng con của mình, thì tiêu đề hoạt động cũng thay đổi thành ngôn ngữ đã chọn, nhưng sau đó các thay đổi chỉ được áp dụng cho đoạn tôi đã gọi trong phương thức dọc, tại sao lại như vậy ?
Abhinav Chauhan

@AbhinavChauhan Tôi không chắc điều này có đúng không. Tôi cần kiểm tra cái đó. Tôi chưa bao giờ phải đối mặt với vấn đề này khi tôi thực hiện giải pháp này. Tuy nhiên, đã lâu và có thể có một số thay đổi trong việc triển khai Android cho các phiên bản mới hơn. Ngoài ra, hãy thử một số câu trả lời mới nhất trên bài đăng này.
sud007

Tôi đã thử nhiều giải pháp nhưng không có giải pháp nào hoạt động hoặc có thể tôi đã triển khai chúng không chính xác, có thể lớp của bạn hoạt động tốt với các hoạt động không, tôi đang sử dụng warpphương thức của nó trong onAttachphân đoạn, trước đây tôi đã nói rằng tôi chỉ cần làm điều đó với phân đoạn hoạt động và ngôn ngữ được thay đổi trong toàn bộ ứng dụng thì đúng, nhưng đối với tất cả các phần mềm khác, ngôn ngữ thay đổi thành tiếng Anh khi thay đổi cấu hình, vì vậy tôi cần đưa onattachtất cả các phần vào và thay vì tệp kê khai, tôi đặt tiêu đề thanh hành động trong mã, bây giờ ứng dụng đang hoạt động như mong đợi. cảm ơn
Abhinav Chauhan

Được chứ! Tôi chắc chắn rằng bạn không phải làm điều này cho mọi màn hình, chỉ hoạt động đầu tiên khởi chạy và bên trong attachBaseContextchức năng mà thôi. Và điều đó làm được điều đó cho tất cả các màn hình. Bạn đã tạo một BaseActivity cho tất cả các hoạt động trong ứng dụng của mình chưa?
sud007

Không, tôi đã cố gắng làm điều đó trong lớp ứng dụng con của mình với suy nghĩ rằng nó sẽ được áp dụng cho toàn bộ ứng dụng, sau đó trong tất cả các phân đoạn, nhưng hóa ra wrap()mã cần được thực thi ở mọi thay đổi cấu hình, vì vậy tôi đã đặt nó vào Hoạt động trừu tượng mà từ đó tất cả các hoạt động khác mở rộng, hiện nó đang hoạt động
Abhinav Chauhan

6

Bạn nên xóa android:configChanges="locale"khỏi tệp kê khai, điều này sẽ khiến hoạt động tải lại hoặc ghi đè onConfigurationChangedphương thức:

@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
    // your code here, you can use newConfig.locale if you need to check the language
    // or just re-set all the labels to desired string resource
}

Xóa android: configChanges = "locale" khỏi tệp kê khai không ngăn ứng dụng khởi động lại. Nó sẽ khởi động lại bất kể điều đó có được thêm vào tệp kê khai hay không.
portfoliobuilder

Tôi không nói rằng việc xóa android: configChanges = "locale" khỏi tệp kê khai sẽ ngăn ứng dụng khởi động lại, tôi đang nói hoàn toàn ngược lại. Bây giờ, đối với trường hợp chúng tôi có android: configChanges = "locale" trong tệp kê khai, nó được sử dụng để ngăn ứng dụng tải lại vào thời điểm tôi viết câu trả lời này, tôi không thể nói chắc chắn đó là trường hợp hiện tại.
Frane Poljak

6

tất cả mã ở trên của @ Uday đều hoàn hảo nhưng chỉ thiếu một thứ (cấu hình mặc định trong build.gradle)

public void setLocale(String lang) { 
Locale myLocale = new Locale(lang); 
Resources res = getResources(); 
DisplayMetrics dm = res.getDisplayMetrics(); 
Configuration conf = res.getConfiguration(); 
conf.locale = myLocale; 
res.updateConfiguration(conf, dm); 
Intent refresh = new Intent(this, AndroidLocalize.class); 
finish();
startActivity(refresh); 

}

Của tôi không hoạt động chỉ vì ngôn ngữ không được đề cập trong tệp cấu hình (build.gradle)

 defaultConfig {
    resConfigs "en", "hi", "kn"
}

sau đó, tất cả các ngôn ngữ bắt đầu chạy


3
nó KHÔNG HOẠT ĐỘNG
Krunal Shah

Nó có thực sự cần thiết không?
JCarlosR

1
@JCarlosR vâng. khi tôi thêm ngôn ngữ vào tệp cấu hình, mã của Udhay bắt đầu chạy
Lokesh Tiwari

3

Những người gặp sự cố phiên bản hãy thử mã này ..

public static void switchLocal(Context context, String lcode, Activity activity) {
        if (lcode.equalsIgnoreCase(""))
            return;
        Resources resources = context.getResources();
        Locale locale = new Locale(lcode);
        Locale.setDefault(locale);
        android.content.res.Configuration config = new 
        android.content.res.Configuration();
        config.locale = locale;
        resources.updateConfiguration(config, resources.getDisplayMetrics());
        //restart base activity 
        activity.finish();
        activity.startActivity(activity.getIntent());
    }

2

Mã mẫu của Udhay hoạt động tốt. Ngoại trừ câu hỏi của Sofiane Hassaini và Chirag SolankI, đối với lối vào lại, nó không hoạt động. Tôi cố gắng gọi mã của Udhay mà không khởi động lại hoạt động trong onCreate (), trước super.onCreate (saveInstanceState) ;. Sau đó, nó là OK! Chỉ có một vấn đề nhỏ, các chuỗi menu vẫn không thay đổi thành Locale đã đặt.

    public void setLocale(String lang) { //call this in onCreate()
      Locale myLocale = new Locale(lang); 
      Resources res = getResources(); 
      DisplayMetrics dm = res.getDisplayMetrics(); 
      Configuration conf = res.getConfiguration(); 
      conf.locale = myLocale; 
      res.updateConfiguration(conf, dm); 
      //Intent refresh = new Intent(this, AndroidLocalize.class); 
      //startActivity(refresh); 
      //finish();
    } 

cùng một vấn đề với chuỗi menu. Bạn có giải quyết được vấn đề?
AlexS

@AlexS, tôi không tìm thấy cách khắc phục sự cố trong chuỗi menu. Nhưng được tìm thấy khi thoát ứng dụng và sau đó vào lại, các chuỗi menu thường có thể được thay đổi thành Ngôn ngữ mới.
Fisher

bạn có ý nghĩa Intent refresh = new Intent(this, ThisActivity.class); startActivity(refresh); ?
AlexS

2
@AlexS, Không! thêm Intent () và startActivity () mới có thể làm cho nó trở về ngôn ngữ mặc định khi khởi động lại ứng dụng. Ý tôi là nếu người dùng thoát ứng dụng và vào lại ứng dụng, các chuỗi menu có thể được thay đổi thành Ngôn ngữ mới.
Fisher
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.