目录

继续了解并学习相关的知识,本次记录有关资源的相关信息。

有关资源(Resource)的信息

资源(resource)是 Java 源代码之外的静态信息块。资源被存储为源文件集(例如,app/src/main/res/)中 res/ 目录下的文件。这里是您可以找到所有图标和其他图像的位置、用于国际化的外部化字符串等。

这些与 Java 源代码是分开的,不仅仅因为它们的格式不同。它们是分开的,因为您可以有多个资源定义,以便在不同情况下使用。例如,通过国际化,您将拥有不同语言的字符串。您的 Java 代码将能够保持在很大程度上忽视这一点,因为 Android 会在给定情况下从所有候选人中选择正确的资源(例如,如果设备的语言环境设置为西班牙语,则选择西班牙语字符串)。

String Theory

将标签和其他一些文本保存在应用程序的主要源代码之外通常被认为是一个非常好的主意。 特别是,它有助于国际化(internationalization - I18N)和本地化(localization - L10N)。即使你不打算把你的字符串翻译成其他语言,如果所有的字符串都在一个地方,而不是分散在整个源代码中,更容易进行更正。

Plain Strings

一般来说,您需要做的只是在 res/values 目录中有一个XML文件(通常名为 res/values/strings.xml),其中包含一个 resources 根元素和一个用于您想要编码为资源的每个字符串的子 string 元素。string 元素接受一个 name 属性,它是这个字符串的唯一名称,以及一个包含字符串文本的文本元素:

<resources>
  <string name="quick">The quick brown fox...</string>
  <string name="laughs">He who laughs last...</string>
</resources>

一个棘手的部分是如果字符串值包含引号或撇号。在这些情况下,你会希望通过在它们前面加一个反斜杠来转移这些值(例如,These are the times that try men\’s souls)。或者,如果它只是一个撇号,你可以用引号括起这个值(例如,“These are the times that try men’s souls.”)。

Styled Text

Android 中的许多内容都可以显示富文本,其中文本已使用轻量级HTML标记进行了格式化:<b>、<i> 和 <u>。您的字符串资源支持这一点,只需像在网页中一样使用HTML标记即可:

<resources>
  <string name="b">This has <b>bold</b> in it.</string>
  <string name="i">Whereas this has <i>italics</i>!</string>
</resources>

CDATA. CDATA Run. Run, DATA, Run.

由于字符串资源 XML 文件是 XML 文件,如果您的消息包含 <、> 或者 & 字符(除了上面列出的格式化标签以外),您将需要使用 CDATA 部分:

<string name="report_body">
<![CDATA[
<html>
<body>
<h1>TPS Report for: {{reportDate}}</h1>
<p>Here are the contents of the TPS report:</p>
<p>{{message}}</p>
<p>If you have any questions regarding this report, please
do <b>not</b> ask Mark Murphy.</p>
</body>    
</html>
]]>
  </string>

The Directory Name

我们的 stub 项目中的字符串资源位于 res/values/strings.xml 文件中。 由于此目录名称(值)没有后缀,因此该目录中的字符串资源对任何情况都是有效的,包括设备的任何区域设置。我们需要额外的目录和不同的 strings.xml 文件来支持其他语言。

Multi-Locale Support

Android 7.0 以上的用户可以表明他们支持多种语言。

这会影响任何与语言环境相关的资源(如字符串)的资源解析。 现在,Android 会检查多种语言以查找资源匹配,然后再回到默认语言(例如,无论您在 res/values/strings.xml 中有何内容)。因此,确保您为每种支持的语言都有一套完整的字符串,以免用户在 UI 中混合使用一组语言,这一点很重要。

您可以通过 LocaleList 类及其 getDefault() 静态方法找出用户请求的语言。顾名思义,这有一个代表用户首选语言的 Locale 对象列表。如果您以前一直在使用 Locale 本身(例如,针对资源之外的专用应用内语言帮助),则您将希望切换到适用于 Android 7.0 及更高版本的 LocaleList。

Got the Picture?

所有 Android 版本都支持 PNG、JPEG 和 GIF 格式的图像。然而,GIF 被正式劝阻,PNG 是整体首选格式。Android 也支持一些专有的基于 XML 的图像格式。许多较新版本的 Android 也支持 Google 的 WebP 图像格式,但这并不是特别受欢迎。

有两种类型的资源使用这些图像:drawables 和 mipmap。事实上,它们几乎完全相同。Mipmaps 主要用于「启动器图标」 - 主屏幕启动器中显示的图标,用于识别用户可以启动的 activity。Drawables 拥有一切。

在 Android 模块中可以有 res/drawable/ 和 res/mipmap/ 目录。但是,您通常不会在这里找到位图。相反,那些驻留在像 res/drawable-mdpi/ 和 res/drawable-hdpi/ 这样的目录中。

这些涉及不同的资源集。后缀(例如 -mdpi、-hdpi)是过滤器,指示在什么情况下应该使用存储在那些目录中的图像。具体来说,-ldpi 表示应该在具有低密度屏幕的设备(大约每英寸120点或「dpi - dots-per-inch」)上使用的图像。 -mdpi 后缀表示中等密度屏幕(大约160dpi)的资源,-hdpi 表示高密度屏幕(大约240dpi)的资源。 -xhdpi 指示用于超高密度屏幕(约320dpi)的资源,-xxhdpi 指示超高密度屏幕(约480dpi),-xxxhdpi指示超高密度屏幕(约640dpi),等等。

Dimensions

Android 中的几个位置使用维度(dimensions)来描述距离,例如小部件的大小。有几种不同的度量单位可供您使用:

  1. px 表示硬件像素(hardware pixels),其大小因设备而异,因为并非所有设备都具有相同的屏幕密度
  2. in 和 mm 分别为英寸和毫米(inches and millimeters),基于屏幕的实际尺寸
  3. pt 为点数(points),在发布条款(in publishing terms)是 172 英寸(同样,根据屏幕的实际大小)
  4. dip(或 dp)用于不依赖于密度的像素(density-independent pixels) - 对于 〜160dpi分辨率屏幕,一个 dip 等于一个硬件像素,但在 〜320dpi 屏幕上一个 dip 等于两个硬件像素
  5. sp 为缩放像素(scaled pixels),其中一个 sp 等于一个正常字体缩放级别的 dip,基于用户在「设置」中选择的字体缩放级别根据需要增加和减少

缺省情况下,Dimension 资源保存在 res/values/ 目录中的 dimens.xml 文件中,该文件也包含您的字符串。

要将维度编码为资源,请将 dimen 元素添加到 dimens.xml 中,并使用名称属性作为此资源的唯一名称,以及表示该值的单个子文本元素:

<resources>
  <dimen name="thin">10dip</dimen>
  <dimen name="fat">1in</dimen>
</resources>

Layouts

项目还有一个 res/layout/ 目录。 这是 UI 布局,描述你的用户界面应该是什么样子。