사용자가 언어를 선택할 때 앱의 언어를 변경하는 방법은 무엇입니까?


106

앱에서 스페인어, 포르투갈어 및 영어의 세 가지 언어를 지원하고 싶습니다. 그리고 앱에서 언어를 선택하는 옵션을 제공합니다.

1) drawable-es, drawable-pt, drawable 3 개의 드로어 블 폴더.

2) 3 개의 값 폴더 values-es, values-pt, values. 언어에 따라 String.xml 값을 변경합니다.

언어를 선택할 수있는 imageView가 있습니다. 클릭하면 영어, 스페인어, 포르투갈어 옵션으로 구성된 메뉴가 열립니다.

이 코드로 옵션 선택시 앱 내부에 로케일을 설정했습니다.

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

Manifest- android : configChanges = "locale" 에서 선언했습니다 .

작동하지만 문제가 있습니다.

문제:-

1) 언어 선택시 언어 선택 이미지로 구성된 화면은 변경되지 않고 다른 화면은 변경됩니다.

2) 방향 변경 후 휴대 전화의 로케일에 따라 앱 복원 언어.


1
2 문제에 대한 추가 시도 : android:configChanges="locale"AndroidManifest.xml을 내부 사용자의 활동에 대해
Parth 트레이 도시

내 매니페스트의 모든 활동을 이미 추가했습니다.
mukesh

언어 목록, 설정 화면의 기본 설정을 제공하고 애플리케이션의 언어를 재정의하는 다음 라이브러리를 사용할 수 있습니다. github.com/delight-im/Android-Languages
caw

답변:


172

웹 페이지 발췌 : http://android.programmerguru.com/android-localization-at-runtime/

사용자가 언어 목록에서 선택하면 앱의 언어를 간단하게 변경할 수 있습니다. 로케일을 문자열 (영어의 경우 'en', 힌디어의 경우 'hi'와 같이)으로 허용하는 아래와 같은 방법을 사용하고 앱의 로케일을 구성하고 언어 변경 사항을 반영하도록 현재 활동을 새로 고칩니다. 적용한 로케일은 수동으로 다시 변경할 때까지 변경되지 않습니다.

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

다음 패키지를 가져 왔는지 확인하십시오.

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; 

활동에 매니페스트 추가 android : configChanges = "locale | orientation"


2
네 물론입니다. 웹 페이지의 일부를 제공 할 수 있습니다. 제공해야 할 부분을 알려주십시오. 감사.
Udhay

3
탐색 스택에 두 개의 활동 사본이 없도록 finish ()를 추가해야합니다.
Joel Teply 2015-06-08

6
finish()전에 호출해야 startActivity(refresh)합니다. 그렇지 않으면 활동이 다시 시작되는 대신 앱이 종료 될 수 있습니다.
Mohammed Ali

10
안녕하세요, 저는 그것을했다, 그것은 작동하지만, 내가 응용 프로그램을 다시 시작할 때, 그것은 .. 기본 언어로 돌아갑니다
소피 Hassaini

5
구성 구성 = new Configuration (newConfig); config.locale = 로케일; 제 경우에는이 메시지를받습니다. 로케일은 API 레벨 25에서 지원 중단됨
Milon

9

좋은 솔루션은 여기에 잘 설명되어 있습니다. 그러나 여기에 하나 더 있습니다.

자신 만의 CustomContextWrapper클래스 확장을 ContextWrapper만들고이를 사용하여 전체 애플리케이션에 대한 로케일 설정을 변경하십시오. 다음은 사용법 이있는 GIST 입니다.

그런 다음 CustomContextWrapper저장된 로케일 식별자 (예 : 'hi'활동 수명주기 메서드에서 힌디어)를 사용 하여를 호출합니다 attachBaseContext. 여기에서 사용 :

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

링크에 대한 감사가이 작동하지만 난 몇 가지를 이해하지 못했지만, 난 그냥 전화 MyContextWrapper.warp에서 onAttach내 응용 프로그램의 한 조각 그러나 언어가 전체 앱 변경되었지만, 활동 제목이 변경되지 않은, 나는 그것을 생각 매니페스트 제목이 우선하기 때문에 onAttachBaseContex응용 프로그램의 하위 클래스 에서 동일한 메서드를 호출하면 활동 제목도 선택한 언어로 변경되지만 변경 사항은 warp 메서드에서 호출 한 조각에만 적용됩니다. ?
Abhinav Chauhan

@AbhinavChauhan 나는 이것이 사실인지 확실하지 않습니다. 나는 그것을 확인해야한다. 이 솔루션을 구현할 때이 문제에 직면 한 적이 없습니다. 그러나 오랜 시간이 지났으며 최신 버전의 Android 구현에 약간의 변경이있을 수 있습니다. 또는이 게시물에 대한 최신 답변을 시도해보십시오.
sud007

나는 많은 솔루션을 시도했지만 그들 중 아무것도 작동하지 않았거나 잘못 구현했을 수 있습니다. 클래스가 활동과 잘 작동하는지, 나는 그것을 조각 warp에서 사용하고 있습니다 onAttach. 이전에 나는 mainactivity 조각과 언어를 변경해야한다고 말했습니다. 전체 앱은 사실이지만 다른 모든 조각의 경우 구성 변경시 영어로 변경되므로 onattach모든 조각 을 입력해야하며 매니페스트 대신 코드에서 작업 표시 줄 제목을 설정하면 앱이 예상대로 작동합니다. 감사합니다
Abhinav Chauhan

괜찮아! 모든 화면에 대해이 작업을 수행 할 필요는 없으며 시작되는 첫 번째 활동과 attachBaseContext함수 내부 에서만 수행 할 수 있습니다. 그리고 그것은 모든 화면에 적용됩니다. 앱의 모든 활동에 대해`BaseActivity '를 만들었습니까?
sud007

아니요, 응용 프로그램의 하위 클래스에서 전체 응용 프로그램에 적용한 다음 모든 조각에 적용하려고 시도했지만 wrap()모든 구성 변경시 코드를 실행해야 한다는 것이 밝혀 졌으므로 다른 모든 활동이 확장되는 추상 활동, 현재 작동 중
Abhinav Chauhan

6

android:configChanges="locale"매니페스트에서 제거 하여 활동을 다시로드하거나 onConfigurationChanged메서드를 재정의해야 합니다.

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

매니페스트에서 android : configChanges = "locale"을 제거해도 앱이 다시 시작되지는 않습니다. 매니페스트에 추가되었는지 여부에 관계없이 다시 시작됩니다.
Portfoliobuilder

매니페스트에서 android : configChanges = "locale"을 제거하면 앱이 다시 시작되지 않는다는 말이 아닙니다. 정확히 반대입니다. 이제 매니페스트에 android : configChanges = "locale"이있는 경우이 답변을 작성했을 때 앱이 다시로드되는 것을 방지하는 데 사용되었으므로 지금의 경우라고 확신 할 수 없습니다.
Frane Poljak

6

위의 모든 @Uday 코드는 완벽하지만 한 가지만 누락되었습니다 (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); 

}

구성 파일 (build.gradle)에 언어가 언급되지 않았기 때문에 내 것이 작동하지 않았습니다.

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

그 후 모든 언어가 실행되기 시작했습니다.


3
ITS NOT WORKING
Krunal 샤

정말 필요한가요?
JCarlosR

1
@JCarlosR 예. 구성 파일에 언어를 추가했을 때 Udhay의 코드가 실행되기 시작했습니다.
Lokesh Tiwari

3

버전 문제가있는 분들은이 코드를 사용해보십시오 ..

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

Udhay의 샘플 코드가 잘 작동합니다. Sofiane Hassaini와 Chirag SolankI의 질문을 제외하고는 재 입장을 위해 작동하지 않습니다. super.onCreate (savedInstanceState); 전에 onCreate ()에서 활동을 다시 시작하지 않고 Udhay의 코드를 호출하려고합니다. 그럼 OK! 약간의 문제 일뿐입니다. 메뉴 문자열이 여전히 설정된 로케일로 변경되지 않았습니다.

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

메뉴 문자열과 동일한 문제. 문제를 해결합니까?
AlexS

@AlexS, 메뉴 문자열에서 문제를 해결하는 방법을 찾지 못했습니다. 그러나 앱을 종료 한 다음 다시 입력하면 메뉴 문자열을 일반적으로 새 로케일로 변경할 수 있습니다.
Fisher

무슨 뜻 Intent refresh = new Intent(this, ThisActivity.class); startActivity(refresh); 입니까?
AlexS

2
@AlexS, 안돼! 새로운 Intent () 및 startActivity ()를 추가하면 앱을 다시 시작할 때 기본 언어로 돌아갈 수 있습니다. 내 말은 사용자가 앱을 종료하고 앱에 다시 들어가면 메뉴 문자열이 새 로케일로 변경 될 수 있다는 것입니다.
피셔
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.