在Android应用程序中,我需要从当前所选资源文件夹以外的资源文件夹中选择资源(界面语言是系统选择的任何一种,但用户可以为TTS选择不同的语言)。由于应用程序的结构方式,切换资源不是一种选择;我同时需要默认设置和备用设置。例如,当用户界面是英文时,我能够使用此代码选择西班牙语字符串:
class SpanishStrings()
{
private Resources mResources;
public Foo(Context context)
{
final Resources oldResources = context.getResources();
Configuration oldConfiguration = oldResources.getConfiguration();
DisplayMetrics metrics = oldResources.getDisplayMetrics();
Configuration configuration = new Configuration(oldConfiguration);
configuration.locale = new Locale("es", "es");
mResources = new Resources(oldResources.getAssets(), metrics, configuration);
}
String getString(int id)
{
return mResources.getString(id);
}
}
但是这也将整个用户界面设置为西班牙语! Android一次只能拥有一个活动资源吗?
这在Android 2.3.4上运行,如果这有任何区别。
答案 0 :(得分:2)
我找到了一种让它发挥作用的方法。给定问题中的类,删除构造函数并更改getString(),如下所示:
String getString(int id)
{
final Resources oldResources = mContext.getResources();
final Configuration oldConfiguration = oldResources.getConfiguration();
final DisplayMetrics metrics = oldResources.getDisplayMetrics();
final Configuration configuration = new Configuration(oldConfiguration);
configuration.locale = new Locale("es", "es");
Resources resources = new Resources(oldResources.getAssets(), metrics, configuration);
final String result = resources.getString(id);
oldResources.updateConfiguration(oldConfiguration, metrics);
return result;
}
这是重要的updateConfiguration。我查看了android.content.res.Resources的代码,结果发现Resources()构造函数调用了updateConfiguration(),而updateConfiguration()调用了mAssets.setConfiguration()。这意味着对配置的任何更改都将应用于同一AssetManager实例的所有用户。
我看起来没有比这更深入了,我知道上面的答案可以通过保留两组资源并且只调用updateConfiguration()而不是在检索字符串之前和之后构造一个全新的Resources对象来优化,所以如果有人知道如何创建一个全新的AssetManager()实例,那么请发布一个比这更好的答案!
编辑: 在我目前的代码中,我通过子类化资源使用它变得不那么痛苦,如下所示:
final oldResources = context.getResources();
final Configuration configuration = new Configuration(mDefaultResources.getConfiguration());
configuration.locale = new Locale("es", "es");
mResources = new Resources(mDefaultResources.getAssets(), mDefaultResources.getDisplayMetrics(), configuration)
{
@Override
public String getString(int id) throws NotFoundException
{
updateConfiguration(getConfiguration(), getDisplayMetrics());
String result = super.getString(id);
oldResources.updateConfiguration(oldResources.getConfiguration(), oldResources.getDisplayMetrics());
return result;
}
};
答案 1 :(得分:0)
尝试修改这样的代码(取自https://stackoverflow.com/a/10879185/446963)
cMK = getResources().getStringArray(R.array.cities);
Configuration confTmp =new Configuration( getResources().getConfiguration());
confTmp.locale = new Locale("en");
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
Resources resources = new Resources(getAssets(), metrics, confTmp);
/* get localized string */
cENG = getResources().getStringArray(R.array.cities);
在您的代码中,您是从原始资源到新资源的指标和资产。所以我认为新资源中的这些对象发生了任何变化,并过滤回原始资源。
正在使用上面的代码为所有需要的资源参数创建新对象。只是一个猜测,但看看它是否有效...