在安卓中是否可以在运行时更新string.xml文件?

3

我想在我的应用程序中动态应用本地化,所以是否有可能在Java文件中定义字符串并将这些字符串提取到我们的布局XML文件中,即像我们替换@string/anystringname一样,将其替换为Java文件中定义的字符串,例如@somestring?


1
“是否可以……” 不行。您不能在运行时修改资源文件。 - Phantômaxx
但肯定有一种编程方式可以获取这些ID吧? - Shailee
3个回答

6
基本上不行。
您无法动态操纵资源文件。 您需要自己实现这样的功能。
以下是一个例子:
english.json
{
    "hello": "Hello"
}

french.json

{
    "hello": "Bonjour"
}

public class StringManager {
    private static StringManager sInstance = null;
    private static String sDefaultLanguageCode = "en";

    private Map<String, JSONObject> mLanguageMap = new ArrayMap<>();

    private StringManager() {
    }

    public static StringManager getInstance() {
        if (sInstance == null) {
            synchronized (StringManager.class) {
                if (sInstance == null)
                    sInstance = new StringManager();
            }
        }
        return sInstance;
    }

    public static void setDefaultLanguageCode(String languageCode) {
        sDefaultLanguageCode = languageCode;
    }

    public void addLanguage(String languageCode, JSONObject json) {
        mLanguageMap.put(languageCode, json);
    }

    public String getString(String key) {
        return mLanguageMap.get(mDefaultLanguageCode).getString(key);
    }

    public String getString(String languageCode, String key) {
        return mLanguageMap.get(languageCode).getString(key);
    }
}

public class SomeActivity extends Activity {
    ...
    public void initStringResources() {
        // assume englishJsonObject is created from english.json
        StringManager.getInstance().addLanguage("en", englishJsonObject);
        StringManager.getInstance().addLanguage("fr", frenchJsonObject);

        StringManager.setDefaultLanguageCode("fr");
    }

    public void useSomeString() {
        String helloString = StringManager.getInstance().getString("hello");
        // helloString will be "Bonjour"

        // and you can get specific language string
        String englishHelloString = StringManager.getInstance().getString("en", "hello");
    }

    // this may be called from Button or other UI component
    public void onLanguageChanged(String languageCode) {
        StringManager.setDefaultLanguageCode(languageCode);
        // and update UI components that display localized strings
    }
}

嗨,我尝试了你的解决方案,但它没有起作用。我可以把文件放在资产文件夹中,然后在读取该文件后将该文件用于布局吗? - Shailee
正如我之前所提到的,你无法在运行时更改XML文件。如果你尝试了我的解决方案 <TextView android:text="@string/hello"/> 那么,当然不会起作用。 相反,你可以通过编程方式设置TextView的文本。 如果你在XML文件中声明了一个TextView,如下所示: <TextView android:id="@+id/my_textview"> 你可以按以下方式使用我的解决方案; TextView textView = (TextView) findViewById(R.id.my_textview); textView.setText(StringManager.getInstance().getString("hello")); - nexus5x
好的,我明白了你的解决方案。我需要以编程方式实现它,只需创建一个通用函数并调用字符串即可。 - Shailee
看这个,有一个库可以实现相同的功能,并添加了异步处理。 https://github.com/B3nedikt/restring - ArpitA

0

这是不可能的。但是在运行时更改应用程序的语言是可能的。这允许您在不同语言的strings.xml之间切换。 我用于此的库是Android本地化库 所有活动都必须扩展LocalizationActivity,该类又扩展了AppCompatActivity。您只需调用 setLanguage("en"); 即可更改应用程序的语言,并使用不同的strings.xml

此线程中,您可以阅读更多可能的解决方案。


可以通过不同语言的values文件夹来获取所有字符串,但如何动态地实现而无需输入所有不同语言的字符串呢?即如果我为所有字符串创建JSON并将其存储在数据库中,通过键值获取并在布局文件中使用该字符串。 - Shailee
@Shailee 这个解决方案只有在将本地化放在strings.xml中时才可用。该库允许您切换语言。现在使用不同语言的strings.xml,这允许动态本地化。但是,如果您想从数据库检索本地化字符串,则最好的选择可能是子类化TextView并添加自定义属性。https://developer.android.com/training/custom-views/create-view.html。在您的TextView中,您可以实现读取正确字符串的逻辑。 - Rockney
好的,那么通过使用本地化库,在按钮点击时动态更改语言而无需为不同语言创建新的字符串文件,这是否可行? - Shailee
可以在按钮点击时动态更改语言。如果您想从其他源读取字符串而不是strings.xml,则应实现自己的逻辑来本地化字符串。为什么不将语言分开放在不同的strings.xml中呢?除非您想要从其他来源加载它们。 - Rockney
是的,但实际上我不想每次都添加string.xml文件进行本地化,而应该动态更改。 - Shailee

-6
<TextView  
android:id="@+id/tv"
android:layout_width="fill_parent" 
android:layout_height="wrap_content" 
android:text="@string/tv"
/>

<string name="tv">old text</string>//old text

final TextView textView = (TextView) findViewById(R.id.rate);
textView.setText("new text");//new text

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接