앱 자체에서 로캘 변경
내 사용자는 앱 내에서 로캘을 변경할 수 있습니다 (전화 설정은 영어로 유지하고 프랑스어, 네덜란드어 또는 기타 언어로 내 앱의 내용을 읽을 수 있습니다 ...).
왜 1.5 / 1.6에서는 완벽하게 작동하지만 2.0에서는 더 이상 작동하지 않습니까?
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case 201:
Locale locale2 = new Locale("fr");
Locale.setDefault(locale2);
Configuration config2 = new Configuration();
config2.locale = locale2;
getBaseContext().getResources().updateConfiguration(
config2, getBaseContext().getResources().getDisplayMetrics());
// loading data ...
refresh();
// refresh the tabs and their content
refresh_Tab ();
break;
case 201: etc...
문제는 사용자가 위의 코드 줄을 겪을 때마다 메뉴가 점점 줄어든다는 것입니다 ...
이것은 축소되는 메뉴입니다.
@Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0, 100, 1, "REFRESH").setIcon(android.R.drawable.ic_menu_compass);
SubMenu langMenu = menu.addSubMenu(0, 200, 2, "NL-FR").setIcon(android.R.drawable.ic_menu_rotate);
langMenu.add(1, 201, 0, "Nederlands");
langMenu.add(1, 202, 0, "Français");
menu.add(0, 250, 4, R.string.OptionMenu2).setIcon(android.R.drawable.ic_menu_send);
menu.add(0, 300, 5, R.string.OptionMenu3).setIcon(android.R.drawable.ic_menu_preferences);
menu.add(0, 350, 3, R.string.OptionMenu4).setIcon(android.R.drawable.ic_menu_more);
menu.add(0, 400, 6, "Exit").setIcon(android.R.drawable.ic_menu_delete);
return super.onCreateOptionsMenu(menu);
}
이 작업을 다시 수행하려면 API 레벨 5에서 어떻게해야합니까?
이 코드를 테스트하려면 전체 코드가 있습니다.
import java.util.Locale;
import android.app.Activity;
import android.content.res.Configuration;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
import android.widget.Toast;
public class Main extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
SubMenu langMenu = menu.addSubMenu(0, 200, 2, "NL-FR").setIcon(android.R.drawable.ic_menu_rotate);
langMenu.add(1, 201, 0, "Nederlands");
langMenu.add(1, 202, 0, "Français");
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()){
case 201:
Locale locale = new Locale("nl");
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
Toast.makeText(this, "Locale in Nederlands !", Toast.LENGTH_LONG).show();
break;
case 202:
Locale locale2 = new Locale("fr");
Locale.setDefault(locale2);
Configuration config2 = new Configuration();
config2.locale = locale2;
getBaseContext().getResources().updateConfiguration(config2, getBaseContext().getResources().getDisplayMetrics());
Toast.makeText(this, "Locale en Français !", Toast.LENGTH_LONG).show();
break;
}
return super.onOptionsItemSelected(item);
}
}
그리고 여기 매니페스트가 있습니다 :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.cousinHub.ChangeLocale"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".Main"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion="3" />
</manifest>
이것이 내가 찾은 것 :
<uses-sdk android:minSdkVersion="5" />
=> 그것은 잘 작동합니다 ...
<uses-sdk android:minSdkVersion="3" />
=> 로캘을 변경할 때마다 메뉴가 축소됩니다 !!!
1.5에서 사용자가 내 응용 프로그램에 액세스 할 수 있도록하려면 어떻게해야합니까 ??
원래 질문을 통해 로케일 자체에 관한 것이 아니라 다른 모든 로케일 관련 질문이이 질문을 참조합니다. 그래서 여기서 문제를 명확히하고 싶었습니다. 이 질문을 내 로케일 전환 코드의 시작점으로 사용했으며 방법이 정확하지 않다는 것을 알았습니다. 구성 변경 (예 : 화면 회전)까지만 해당 특정 활동에서만 작동합니다. 잠시 동안 코드를 가지고 노는 것은 다음과 같은 접근법으로 끝났습니다.
android.app.Application을 확장하고 다음 코드를 추가했습니다.
public class MyApplication extends Application
{
private Locale locale = null;
@Override
public void onConfigurationChanged(Configuration newConfig)
{
super.onConfigurationChanged(newConfig);
if (locale != null)
{
newConfig.locale = locale;
Locale.setDefault(locale);
getBaseContext().getResources().updateConfiguration(newConfig, getBaseContext().getResources().getDisplayMetrics());
}
}
@Override
public void onCreate()
{
super.onCreate();
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
Configuration config = getBaseContext().getResources().getConfiguration();
String lang = settings.getString(getString(R.string.pref_locale), "");
if (! "".equals(lang) && ! config.locale.getLanguage().equals(lang))
{
locale = new Locale(lang);
Locale.setDefault(locale);
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
}
}
}
이 코드는 모든 활동에 사용자 정의 로케일이 설정되도록하며 회전 및 기타 이벤트에서 재설정되지 않습니다.
I have also spent a lot of time trying to make the preference change to be applied immediately but didn't succeed: the language changed correctly on Activity restart, but number formats and other locale properties were not applied until full application restart.
Changes to AndroidManifest.xml
Don't forget to add android:configChanges="layoutDirection|locale"
to every activity at AndroidManifest, as well as the android:name=".MyApplication"
to the <application>
element.
After a good night of sleep, I found the answer on the Web (a simple Google search on the following line "getBaseContext().getResources().updateConfiguration(mConfig, getBaseContext().getResources().getDisplayMetrics());
"), here it is :
link text => this link also shows screenshots
of what is happening !
Density was the issue here, I needed to have this in the AndroidManifest.xml
<supports-screens
android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:anyDensity="true"
/>
The most important is the android:anyDensity =" true ".
Don't forget to add the following in the AndroidManifest.xml
for every activity (for Android 4.1 and below):
android:configChanges="locale"
This version is needed when you build for Android 4.2 (API level 17) explanation here:
android:configChanges="locale|layoutDirection"
In Android M the top solution won't work. I've written a helper class to fix that which you should call from your Application class and all Activities (I would suggest creating a BaseActivity and then make all the Activities inherit from it.
Note: This will also support properly RTL layout direction.
Helper class:
public class LocaleUtils {
private static Locale sLocale;
public static void setLocale(Locale locale) {
sLocale = locale;
if(sLocale != null) {
Locale.setDefault(sLocale);
}
}
public static void updateConfig(ContextThemeWrapper wrapper) {
if(sLocale != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
Configuration configuration = new Configuration();
configuration.setLocale(sLocale);
wrapper.applyOverrideConfiguration(configuration);
}
}
public static void updateConfig(Application app, Configuration configuration) {
if (sLocale != null && Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
//Wrapping the configuration to avoid Activity endless loop
Configuration config = new Configuration(configuration);
// We must use the now-deprecated config.locale and res.updateConfiguration here,
// because the replacements aren't available till API level 24 and 17 respectively.
config.locale = sLocale;
Resources res = app.getBaseContext().getResources();
res.updateConfiguration(config, res.getDisplayMetrics());
}
}
}
Application:
public class App extends Application {
public void onCreate(){
super.onCreate();
LocaleUtils.setLocale(new Locale("iw"));
LocaleUtils.updateConfig(this, getBaseContext().getResources().getConfiguration());
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
LocaleUtils.updateConfig(this, newConfig);
}
}
BaseActivity:
public class BaseActivity extends Activity {
public BaseActivity() {
LocaleUtils.updateConfig(this);
}
}
This is for my comment on Andrey's answer but I cant include code in the comments.
Is you preference activity being called from you main activity? you could place this in the on resume...
@Override
protected void onResume() {
if (!(PreferenceManager.getDefaultSharedPreferences(
getApplicationContext()).getString("listLanguage", "en")
.equals(langPreference))) {
refresh();
}
super.onResume();
}
private void refresh() {
finish();
Intent myIntent = new Intent(Main.this, Main.class);
startActivity(myIntent);
}
I couldn't used android:anyDensity="true" because objects in my game would be positioned completely different... seems this also does the trick:
// creating locale Locale locale2 = new Locale(loc); Locale.setDefault(locale2); Configuration config2 = new Configuration(); config2.locale = locale2; // updating locale mContext.getResources().updateConfiguration(config2, null);
If you want to effect on the menu options for changing the locale immediately.You have to do like this.
//onCreate method calls only once when menu is called first time.
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
//1.Here you can add your locale settings .
//2.Your menu declaration.
}
//This method is called when your menu is opend to again....
@Override
public boolean onMenuOpened(int featureId, Menu menu) {
menu.clear();
onCreateOptionsMenu(menu);
return super.onMenuOpened(featureId, menu);
}
참고URL : https://stackoverflow.com/questions/2264874/changing-locale-within-the-app-itself
'IT story' 카테고리의 다른 글
반응 성분 대 반응 성분 (0) | 2020.05.13 |
---|---|
메모장 ++이 파일의 모든 단어에 대해 자동 완성을 표시하지 못하게하는 방법 (0) | 2020.05.13 |
C ++에서 벡터를 초기화하는 방법 (0) | 2020.05.13 |
CSS에서“! important”를 사용하면 어떤 의미가 있습니까? (0) | 2020.05.13 |
jQuery로 RSS 구문 분석 (0) | 2020.05.12 |