如何在Android应用程序中参数化所有字符串

时间:2019-06-24 15:31:38

标签: android

我正在构建一个应用程序,并且正在考虑如何“参数化”应用程序中的所有字符串(甚至可能),以便允许我轻松地更改它们而无需再次“重新部署”它…… >

表示它将位于带有字符串的文件中(例如,使用模板和其他语言时,您在PHP中有PO文件),我可以在其中进行管理。

当我想使用其他语言时可能会有用:)

我在这方面有点挣扎,所以我在想,如果您可以给我一个提示,或者告诉我在哪里“去”研究应该如何实施..

谢谢

5 个答案:

答案 0 :(得分:1)

如果您想在应用程序中使用其他语言,请根据需要创建尽可能多的strings.xml文件。但是,当您添加新的字符串文件时,必须重新部署。

为避免这种情况,您应该在后端调用特定的API,该API会根据设备的语言向您发送所有文本。为此,您必须前后管理。

答案 1 :(得分:0)

因此,如果我正确地理解了您的问题,请打开res - >value folder -> strings.xml - >,您会看到类似以下的内容:

<string name="app_name">this is your app name</string>

现在,每当您希望文本为“这是您的应用名称”时,您要做的就是添加以下行:

android:text="@string/app_name"

当您更改strings.xml中的实际字符串时,它也会在他使用的每个位置(android:text="@string/app_name")中更改

答案 2 :(得分:0)

Android具有用于资产资产本地化的内置机制(包括字符串) https://developer.android.com/guide/topics/resources/localization#creating-alternatives

答案 3 :(得分:0)

您尝试做的事情被称为“ 本地化”,如果您想为用户提供不同的语言支持和类似的东西,这可能会有所帮助。

在android中,这是通过将所有字符串放在 res 文件夹中的 Strings.xml 文件中来完成的。

如果您使用的是android studio,只需在任何硬编码字符串上按 Alt + Enter ,然后从弹出菜单中选择“提取字符串资源” ,输入名称弦和瞧!你完成了。

这也是良好编码习惯的一部分,实际上,如果您键入任何硬编码的字符串,您可能会在布局文件中注意到“掉毛警告”,并且它要求您将此字符串添加到strings.xml文件中

您可以为要包含的每种语言创建一个单独的字符串文件。

答案 4 :(得分:0)

选项1

使用默认的内置机制

您已经对此有了答案,或者您可以read the official documentation对此进行解答。 本质上,您维护着一个名为xml的{​​{1}}文件,它是字符串的键值。每个文件(一种语言)将位于strings.xml文件夹中。例如:对于法语,您需要values。每个文件将包含所有已翻译的字符串。如果在法语中找不到值,则会搜索英文文件作为后备。如果没有钥匙,该应用程序将崩溃(如果我没记错的话)。

专业人士

  • 包含在系统中
  • 支持多种语言
  • 在编译时打包,始终可用。

缺点

  • 资源在编译后为“只读”;您不能更改字符串并以这种方式保存更改。

选项2

自己动手做。

如果您需要能够动态更改这些字符串,则需要一些关键要素:

  1. 一种获取/下载所述字符串的方法。
  2. 如果第1步失败,则为默认值(如果用户无法下载,该怎么办?),您需要默认值。
  3. 为确保每个小部件需要显示文本,请调用您自己创建的类,该类可以管理所述动态字符串(我将在下面详细说明)
  4. 您需要知道在某种程度上神奇地丢失了String时该怎么做;因为这是动态的,所以必须在没有找到字符串的情况下进行回退(请参见2)
  5. 这必须相对较快(构造字符串和UI元素时,您不希望进行昂贵的查找)。

专业人士

  • 您可以按照最适合您的方式进行建模
  • 您将能够按照自己的意愿加载字符串,甚至在运行时更改它们。

缺点

  • 您必须构建所有这些内容。
  • 这容易出错,并且很可能比本地解决方案慢。
  • 您必须确保您不会错过任何字符串,并确保您拥有dafults。
  • 您必须修改普通的小部件(例如TextView)以了解如何获取字符串(或者您必须始终提供它们),而且这不会自动进行,您要么必须委托或子类化为values-fr/strings.xml(名称...只是草稿;))
  • 您必须通过将字符串保存在不再需要的内存中来确保不会泄漏内存。
  • 如果要(坚持)“持久化”这些下载的语言,则必须编写/使用自己的持久性机制(通过写入文件或使用某些数据库,共享首选项不是这些的地方) 。
  • 您需要缓存它们(参见上文)并管理字符串的有效性(如果它们变旧了,它们会变旧吗?什么时候应该重新获取它们?)

正如您所看到的那样,它并不简单,每个应用程序都有其自己需要解决的问题,但这大致就是它的意思。

至于“代码” ...我能想到的最简单的方法(或者说,最基本的基础知识)是:

  1. 找到一种“存储”字符串的方法:例如:

YourCustomTextViewThatUnderstandsYourStringThing extends TextView

因此,在此Map中,您存储了KEY(用于查找值)和VALUE:

Map<String, String> oneLanguage

  1. 将所有字符串保留在内存中的一个位置: oneLanguage.put("app_name", "My Super App")

那么您就这样做了

Map<String, Map<String, String>> allLanguages

现在您可以添加其他语言:

allLanguages.put("English", oneLanguage);

现在,您可以在其中存储(存储)每种语言的所有键/值。

当您要检索西班牙语时,您将使用类似以下方法:

anotherLanguage.put("app_name", "Mi Super App"); //my Spanish is top-notch
allLanguages.put("Spanish", anotherLanguage);

然后,您需要(手动,通过子类化或任何您认为更方便的方法)将这些字符串设置为:

String getString(@NonNull String locale, @NonNull String key) {
   return allLanguages.get(locale).get(key);
}

您对这最后一步采取哪种方法完全取决于您。

通常,以上所有内容都是伪代码,并且不是此方法的完整解决方案。您想做的事情:询问设备正在使用的语言环境,跟踪正在使用的语言环境(这样就不必每次都通过它),从服务器中获取这些语言环境(未显示):),并保持将它们保存到磁盘上,以及将用户选择的“区域设置”键保存到共享的首选项中,将方法添加到您的// I mean, don't hardcode the locale... but you get the idea. appNameTextView.setText(yourLanguageManager.getString("Spanish", "app_name")); 中,以便可以进行以下操作:

  • yourLanguageManager
  • boolean updateLocale(String locale, Map<String, String newStrings)
  • boolean deleteLocale(String locale)
  • 等等。你明白了。

总而言之,它只是一个简单的数据结构,可以包含键和值。

祝你好运!