2013-07-11 41 views
0

在Android应用程序中,我需要从资源文件夹中选择除当前所选资源之外的资源(界面语言是系统选择的任何内容,但用户可以为TTS选择不同的语言)。由于应用程序的结构化方式,交换资源不是一种选择;我需要同时设置默认设置和替代设置。我能够使用此代码,例如,选择西班牙语字符串时,用户界面是英文:如何从当前Android资源文件夹中选择一个字符串?

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

尝试修改代码如下(从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); 

在你的代码是新的资源指标和资产从原来的资源。所以我认为新资源中的这些对象发生了任何变化,并过滤回原始资源。

使用上面的代码正在为所有需要的资源参数创建新对象。只是一个猜测,但看看它是否工作...

+0

上面的代码使用原有资产()也和我上面的代码已经创建一个新的配置。唯一不同的是Metrics,但我会试一试。 –

+0

对不起,没有工作,但现在我想我知道为什么!创建新资源会更新资产,AssetManager不会提供我可以看到的自我复制方法。 –

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; 
     } 
    }; 
相关问题