如何从当前的Android资源文件夹中选择字符串?

时间:2013-07-11 22:30:24

标签: android android-resources

在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上运行,如果这有任何区别。

2 个答案:

答案 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);

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

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