使用strings.xml在数据库中存储多语言值的最佳方法是什么?

3

这是我的第一个问题 :)

我正在开发一个将动物物种存储在数据库中的应用程序。该应用程序必须支持多语言,因此我想利用使用strings.xml资源文件的优势。

我的想法是在数据库中存储物种的英文名称,例如“cat”,“dog”等,然后根据类似以下xml(用于意大利语)的实际翻译向用户显示:

<string name="dog">Cane</string>
<string name="cat">Gatto</string>

问题在于R.string包含名称为dog和cat的内容,但它们实际上是int类型的,所以我正在寻找一种使用字符串“dog”来比较R.string.dog翻译值的方法。
我几乎确定我的设计非常错误,但不知道正确的做法,因为应用程序目前处于开发的早期阶段。
谢谢。
编辑示例:
这个例子说明了问题:
数据库数据:
行1: id="1",value="dog"
行2: id="2",value="cat"
字符串文件strings.xml:
<string name="dog">Dog</string>
<string name="cat">Cat</string>

文件字符串 strings-it.xml:

<string name="dog">Cane</string>
<string name="cat">Gatto</string>

我的问题是:用户想要用他们的母语插入一种物种(例如,“Cane”),我希望在插入之前在数据库中搜索它是否已经存在。
我应该循环遍历数据库中的每一行(其中值以英文存储),获取每一行的翻译(例如:我找到了“cat”,然后将其翻译为“Gatto”),并与用户输入进行比较。
这样做是可行的吗?
3个回答

6
如果您想使用一个字符串名称,可以使用getIdentifier()来获取字符串id。例如,要查找R.string.cat
Resources res = getResources();
int stringId = res.getIdentifier("cat", "string", packageName);

在上面的例子中,如果找不到R.string.cat,它会简单地返回0。这是一个简单的测试,可以看到字符串是否存在。

另外,您可以通过使用以下方式之一获取R.java中所有字符串ID的数组:

Field[] fields = R.string.class.getFields();
int[] ids = new int[fields.length];
for(int i=0;i<field.length;i++)
    ids[i] = field[i].getInt(null);

当然,这也会查找您不打算作为翻译的任何字符串,例如对话框/窗口标题、标签/按钮标题等。一般情况下我不建议这样做。如果非要这么做,我会在“翻译”字符串前加上一些东西,以便轻松区分哪个是哪个,比如“entry_cat”。
请注意,我们正在使用反射,如果您有很多字符串,它可能会减慢速度。如果您要循环遍历R.java,则建议只在启动时执行,并将值保存在某种数组/列表中。

谢谢!这正是我正在寻找的!与此同时,我发现了另一种设计我的数据库的方式,类似于https://dev59.com/LnNA5IYBdhLWcg3wgeSk。这个帮助对我的应用程序中的其他功能也可能有用。很抱歉我不能点赞,因为我是新手。 - Scognito
一般来说,那可能是更好的数据库设计。不过 getIdentifier 在其他领域也很有用。至少对我来说是这样,所以记住它也不是坏事。 - Geobits

-1

首先请阅读这篇文章。

http://developer.android.com/training/basics/supporting-devices/languages.html

您可以创建包含多种语言的value文件夹,例如日语、荷兰语等。

您可以在项目的res文件夹中找到value文件夹,并创建新的value文件夹。

res/
       values/
           strings.xml
       values-es/
           strings.xml
       values-fr/
           strings.xml

只需使用Google翻译将您的单词翻译成任何语言,并放入string.xml文件中即可。


1
正如我在另一个回答中所述,我知道如何静态地使用资源文件,问题是如何动态地做到这一点:我已经用一个示例更新了问题。 - Scognito
这些是已知的事实,因此对于原始问题毫无用处。 - D4ddy

-2

首先,开始阅读这里

假设您的应用程序默认语言为英语。同时,假设您想将应用程序中的所有文本本地化为法语,并将应用程序中的大部分文本(除了应用程序的标题)本地化为日语。在这种情况下,您可以创建三个备选的strings.xml文件,每个文件存储在特定于区域设置的资源目录中:
res/values/strings.xml 包含应用程序使用的所有字符串的英文文本,包括名为title的字符串的文本。 res/values-fr/strings.xml 包含所有字符串的法语文本,包括title。 res/values-ja/strings.xml 包含除title以外的所有字符串的日语文本。如果您的Java代码引用R.string.title,则运行时会发生以下情况:
如果设备设置为除法语以外的任何语言,则Android将从res/values/strings.xml文件加载title。 如果设备设置为法语,则Android将从res/values-fr/strings.xml文件加载title。 请注意,如果设备设置为日语,则Android将在res/values-ja/strings.xml文件中查找title。但是,由于该文件中没有包含这样的字符串,因此Android将退回到默认值,并从res/values/strings.xml文件中加载英文的title。

谢谢您的回复。我知道如何使用本地化,因为我的小部件(按钮和标签)已经正确翻译了。我的问题出现在当我搜索现有物种时,例如我想在我的数据库中搜索“cane”(英语中的狗),而所有值都以英语存储时。我该如何进行动态翻译并将存储的值与R.string.值进行比较? - Scognito
问题在于您需要在res文件夹中创建单独的文件夹,例如values-frvalues-es,以便可以相应地使用它们。 - g00dy
我再重复一遍:我知道如何使用翻译。我的问题是编写像这样的查询:select * from species where $inputSpecieInItalian = $dbspecieInEnglish。 - Scognito
那么为什么不将<string name="cane">Dog</string>放入资源中,这样当搜索“cane”时,您就可以获取该名称的资源并可视化其背后的字符串值。 - g00dy

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