1.
使用主题背景编辑器设计应用主题背景
Android Studio 包含被称为主题背景编辑器的视觉辅助工具,以帮助您:
- 创建和修改应用的主题背景。
- 调整不同资源分类器的主题背景。
- 可视化更改公共 UI 元素颜色的效果。
本页面介绍您可以使用主题背景编辑器执行的基本任务,并说明如何执行此类任务。
主题背景编辑器基础知识
本部分描述主题背景编辑器的访问方式及其布局方式。
访问主题背景编辑器
主题背景编辑器的打开方式有两种:
- 在打开的样式 XML 文件(例如
styles.xml
)中,点击文件窗口右上方旁边的 Open editor。 - 在 Tools 菜单中点击 Android > Theme Editor。
在主题背景编辑器中导航
主题背景编辑器的主屏幕分为两个部分。当您向应用栏或凸起的按钮等特定 UI 元素应用当前主题背景时,此编辑器的左侧会显示此类元素的外观。此编辑器的右侧显示要预览的当前主题背景的名称、定义主题背景所在的模块以及 Theme parent 和 colorPrimary 等主题背景资源的设置。您可以更改这些资源设置,以修改设计的主题背景。
主题背景和颜色
主题背景编辑器可用于创建新的主题背景,修改现有的主题背景,以及管理构成主题背景的颜色。
创建新主题背景
要创建主题背景,请按以下步骤操作:
- 打开主题背景编辑器右上方旁边的 Theme 下拉菜单。
- 点击 Create New Theme。
- 在 New Theme 对话框中,为新主题背景输入一个名称。
- 在 Parent theme name 列表中,点击供主题背景从中继承原始资源的父主题背景。
重命名主题背景
要重命名主题背景,请按以下步骤操作:
- 打开主题背景编辑器右上方旁边的 Theme 下拉菜单。
- 点击 Rename 主题背景名称。
- 在 Rename 对话框中,为主题背景输入一个新名称。
- (可选)要查看更改效果,请点击 Preview。
- 要应用更改,请点击 Refactor。
更改颜色资源
要更改 colorPrimary 等现有颜色资源,请按以下步骤操作:
- 点击您要更改的资源名称旁边的彩色方框。此时将显示 Resources 对话框,此对话框左侧显示颜色列表,右侧显示当前所选资源颜色的设置和信息。
- 通过执行以下操作之一,设置主题背景资源的颜色:
- 从颜色列表中选择一种材料调色板颜色。
- 从颜色列表中选择一种已在项目中定义的颜色,也可以根据需要选择修改颜色值、不透明度和名称。
- 点击 Resources 对话框左下方下拉菜单中的 New Resource > New color Value,在项目中定义新的颜色,然后指定颜色值、不透明度和名称。
- 如果您已创建或修改自定义的项目颜色,则可以点击 Custom color 旁边的 CLOSEST MATERIAL COLOR,以确保此颜色与最接近的材料调色板颜色匹配。Android Studio 将您选择的颜色的颜色和不透明度值更改为最接近此颜色的材料颜色,并使用材料调色板中的颜色名称替换 Custom color。
查看状态列表和颜色
在主题背景编辑器中,您可以预览与不同状态关联的颜色。为此,请点击可编辑状态列表资源名称旁边的颜色集方框,以打开 Resources 对话框。Resources 对话框会显示状态列表(例如 Selected)以及与此状态关联的颜色值。点击某种状态的颜色以选择其他颜色值。
为了更全面地控制这些状态,您可以直接在定义状态的 XML 文件中查看和编辑状态的属性。如需了解详细信息,请参阅
ColorStateList
类的文档。设备特定配置
您可以选择应用支持的设备特定配置。为此,请执行以下步骤:
- 点击靠近 Resources 对话框底部的 Device Configuration 旁边的三角形。Device Configuration 部分将会展开,并显示源集和包含资源的 XML 文件的名称,以及存放此文件的配置特定目录的列表。
- 如有必要,可更改 XML 文件名。
- 选中您希望支持的设备特定配置所对应的目录旁边的框。您未指定目录的任何配置将默认使用
values
目录。
如需了解有关目录名称与配置之间关系的详细信息,请参阅支持多种屏幕。如需了解有关支持的目录名称的详细信息,请参阅提供资源。
2.
使用翻译编辑器本地化UI
翻译编辑器提供所有默认和翻译字符串资源的统一且可编辑的视图。
有关翻译不同语言的应用程序的介绍,请阅读 支持不同的语言和文化。
图1.在翻译编辑器显示应用文本翻译之前
字符串资源
项目的字符串资源包含在strings.xml
文件中。您的项目有一个默认strings.xml
文件,其中包含应用程序默认语言的字符串资源,这是您希望大多数应用程序用户都能说的语言。您还可以翻译strings.xml
包含您希望应用程序容纳的其他语言的字符串资源的文件。
strings.xml
完成 默认文件后,您可以自行添加翻译,或者支付专业服务进行翻译。无论哪种方式,您都应该利用Android Studio功能来帮助您管理和测试可本地化的文本。有关专业翻译服务的信息,请参阅订单翻译服务。
打开翻译编辑器
您可以从Android Studio中的以下位置访问翻译编辑器。
从Android视图打开
- 在左侧的Project> Android面板中,选择ModuleName > res> values。
- 右键单击strings.xml文件,然后选择“ 打开翻译编辑器”。
翻译编辑器显示文件中的键和值对
strings.xml
。注意: 当您翻译
strings.xml
文件时,您的项目有多个相应的 值文件夹,后缀表示语言,例如 西班牙语的值-es。您的默认strings.xml
文件始终位于 值(无后缀)文件夹中。
图1显示了翻译工作完成之前简单应用程序的翻译编辑器中的默认应用程序文本(在本例中为英语)。翻译strings.xml
文件的内容 将显示在Untranslatable列的右侧,每种语言一列,如图2所示。
从strings.xml中打开
您可以从任何文件中访问翻译编辑器strings.xml
。
- 在左侧的Project> Android面板中,选择 ModuleName > res> values。
- 双击strings.xml以将其打开以进行编辑。
- 在strings.xml中,单击右上角的“ 打开编辑器”链接。
注意:如果单击“ 隐藏通知”链接,则“ 打开编辑器”链接将消失。要将其恢复,请关闭并重新打开该项目。
从设计编辑器打开
您可以从布局编辑器的设计编辑器中打开翻译编辑器,以编辑默认和翻译的文本,以更好地适应您的布局。有关在设计编辑器中切换语言的信息,请参阅在设计编辑器中显示已翻译的文本。
- 在左侧的Project> Android面板中,选择 ModuleName > res> layout。
- 双击content_main.xml以将其打开以进行编辑。
- 单击左下角的“ 设计”选项卡以显示“ 设计编辑器”。
- 在“设计编辑器”中,选择“ 语言” 下拉列表。
- 选择编辑翻译 。
配置不可翻译的行
在翻译编辑器中,您可以选择Unstranslatable以指示您不希望翻译此行中的文本。您不希望翻译的文本可能是特定于产品的文本,如商品名称和商标,或者没有翻译的技术术语。
当您检查Untranslatable时,默认strings.xml
文件中的相应行 会添加translatable =“false”。在以下示例中, 顶部的EasyApp未翻译,因为它是产品名称。
<resources> <string name = “app_name” translatable = “false” > EasyApp </ string> <string name = “action_settings” > 设置</ string> <string name = “easy_app” > 我是一个简单的应用程序!</ string> <string name = “next_page” > 下一页</ string> <string name = “second_page_message” > 我是第二页!</字符串>
“title_activity_second” > SecondActivity </ string> </ resources>
添加和删除语言
的翻译编辑器支持 BCP 47,并结合区域和区域(国家)代码转换成用于靶向本地化单个选择。语言环境定义的不仅仅是语言。区域设置包括与日期和时间,货币和小数等内容相关的国家/地区格式。
要添加语言,请执行以下操作:
- 在“ 翻译编辑器”中,单击地球图标 。
- 从下拉列表中,选择要添加的语言。
新语言出现在翻译编辑器中, 带有文件的values- *文件夹
strings.xml
将添加到项目中。例如, 西班牙语的值为es。
要删除语言,请执行以下操作:
您可以通过删除列中的每个值来删除翻译编辑器中的语言(请参阅 编辑,添加或删除文本),也可以删除该语言的项目文件夹,如下所示:
- 在左侧的Project> Android面板中,选择 ModuleName > res。
- 右键单击要删除的语言的values- *文件夹。例如, 印地语的值为hi。
- 从下拉列表中,选择“ 删除”以删除该文件夹及其 strings.xml文件。
编辑,添加和删除文本
您可以直接在strings.xml
文件中或通过翻译编辑器操作文本设置。本节介绍 翻译编辑器方法。在翻译编辑器中,您可以通过列表视图或翻译编辑器底部的翻译字段编辑,添加或删除文本。
图2.顶部的列表视图和底部的Translation字段
列表显示
要编辑或添加文本,请执行以下操作:
- 双击要编辑的单元格或添加文本。
- 进行键盘复制粘贴,或者如果您有支持变音符号的键盘,请直接在列表视图中键入。
- 选项卡或将光标移出字段。
要删除文本,请执行以下操作:
- 双击要删除的单元格。
- 在列表视图中,选择文本并按Delete。
- 选项卡或将光标移出字段。
翻译领域
要编辑或添加文本,请执行以下操作:
- 在列表视图中,单击要编辑的单元格或添加文本。
- 在“ 翻译”字段中,执行键盘复制粘贴,或者如果您的键盘支持变音符号,请直接在“ 翻译”字段中键入。
- 选项卡或将光标移出字段。
要删除文本,请执行以下操作:
- 单击要删除的单元格。
- 在“ 翻译”字段中,选择文本并按“ 删除”。
添加和删除密钥
在“翻译编辑器”中,“ 键”列列出了strings.xml
文件中每个数据项的唯一标识符。您可以通过翻译编辑器添加和删除键。删除密钥时,“翻译编辑器”会删除该密钥及其所有相关翻译。翻译编辑器使用安全删除重构来删除密钥,以便您知道密钥文本是否在其他地方使用,并且在删除密钥之前有机会进行必要的调整。安全删除重新定位可确保在删除密钥后仍然可以编译代码。
要添加密钥,请执行以下操作:
- 在“ 翻译编辑器”中,单击“ 添加密钥” 。
- 在对话框中,输入密钥名称,默认值以及默认strings.xml文件的位置。
图3.添加密钥
要删除密钥,请执行以下操作:
- 在“翻译编辑器”中,选择要删除的键。
- 单击删除密钥 。
-
在“ 删除”对话框中,确定是否要安全删除以及是否要在注释和字符串中进行搜索,然后单击“ 确定”。
图4.删除对话框
如果没有对已删除密钥的引用(用法),或者所有引用都是安全可折叠的,则删除密钥。否则,“翻译编辑器”将显示“ 检测到的 用途”对话框,其中包含有关检测到的问题的信息
图5.删除对话框
- 选择查看用法以查看将删除的内容。“ 查找安全删除冲突”对话框显示了不安全删除的所有用法,因此您可以编辑相应的代码。
图6.不安全的用法
- 右键单击用法以显示上下文菜单,然后选择“ 跳转到源”,以便进行所需的更改。
- 在“ 查找安全删除冲突”面板中,选择“ 重新运行安全删除”以确保没有其他需要注意的用法。
- 清除用法后,单击“ 执行重构”以删除密钥。
纠正错误
图7显示了翻译编辑器,显示了英语,西班牙语和法语 strings.xml
文件的内容。红色文本表示有错误的行。
图7.红色文本表示您必须修复的错误情况
要更正错误,请执行以下操作:
- 将鼠标悬停在红色文本上可显示问题及其解决方案的说明。
- 要更正错误,请将鼠标悬停在红色文本上以显示问题及其解决方案的说明。
在“ 翻译编辑器”中进行更改时,基础 strings.xml
文件将随更改一起更新。在strings.xml
文件中进行更改时,“ 翻译编辑器”中的相应列将 随更改一起更新。
翻译示例编辑器更正:
- 图7显示app_name行已经过Untranslatable检查,但提供了西班牙语翻译。删除西班牙语翻译以更正错误。
- 图7显示next_page行缺少法语翻译。使用键盘将Page Suivante复制到单元格中以更正错误。键盘复制粘贴操作将带有变音符号的文本复制到单元格中。
在设计编辑器中显示翻译的文本
要查看翻译文本在应用布局中的显示方式,请在设计编辑器中切换默认和翻译版本之间的文本,如下所示:
- 在左侧的Project> Android面板中,选择 ModuleName > res> layout。
- 双击content_main.xml以将其打开以进行编辑。
- 单击左下角的“ 设计”选项卡以显示“ 设计编辑器”。
- 在“设计编辑器”中,选择“ 语言” 下拉列表。
- 选择编辑翻译 。
- 选择您要用于查看应用的语言。
图8.选择了西班牙语的语言下拉列表
设计编辑器以所选语言显示您的应用程序布局,在本例中为西班牙语。
图9.设计编辑器以西班牙语显示翻译文本
将设计编辑器设置为默认语言
要将语言设置回默认值,请选择es>语言 。
图10.设置为默认语言
管理和测试可本地化的文本
Android平台和Android Studio提供了多种功能,可帮助您管理和测试可本地化的应用文本。这些功能可以帮助您定位从右到左(RTL)脚本(如阿拉伯语或希伯来语)的问题。测试可本地化的文本允许您在将消息提交到源存储库以便稍后发送以进行转换之前,对UI文本及其布局进行调整。
重构您的项目以获得RTL支持
Android Studio具有重构命令,可以支持和/和 元素中的双向文本TextView
, 以便您的应用程序可以显示并允许用户以从左到右(LTR)和从右到左(RTL)脚本编辑文本。该命令还提供应用程序UI布局和所有视图窗口小部件的自动镜像。要查看文本方向更改和布局镜像,还必须 在布局编辑器中设置 文本和布局方向属性。 ConstraintLayout
LinearLayout
以下过程说明如何重构项目以获得RTL支持:
- 选择Refactor> Add RTL support尽可能显示如图11所示的对话框。
图11.添加RTL支持
- 如果文件中的
<application>
元素AndroidManifest.xml
没有该android:supportsRTL="true"
属性,请选中“ 更新AndroidManifest.xml”复选框。 - 如果您的应用
targetSdkVersion
是17或更高,请选择用开始/结束属性替换左/右属性。在这种情况下,您的属性应使用“开始”和“结束”而不是“左”和“右”。例如,android:paddingLeft
成为android:paddingStart
。 - 如果您的应用程序
targetSdkVersion
是16或更少,请选择 生成-v17版本 在这种情况下,您的XML应使用这两组属性。例如,您的XML应该使用android:paddingLeft
和android:paddingStart
。
- 如果文件中的
- 要显示“ 查找重构预览”窗口,请单击“运行”。
图12.检查预览
- 单击“ 执行重构”。
有关重构项目以获得RTL支持的更多信息,请参阅 Android 4.2中的Native RTL支持。
文本和布局方向属性
右边的属性窗口中提供了textDirection文本控件和使用性质的layoutDirection属性与布局小部件用于更改文本和布局组件的方向。方向属性列在右侧的“ 属性”窗口中,并使用API级别17或更高级别。
要查看文本方向更改和布局镜像,还必须 重构项目以获得RTL支持。在英语中,文本方向更改仅从文本的右侧向左侧移动标点符号; 例如,“Hello World!” 成为“!Hello World”。要查看LTR文本切换到RTL,您必须在应用程序中使用RTL语言。如果您想使用英语并查看文本切换到RTL以进行测试,请使用pseudolocales。Pseudolocales独立于重构命令和方向属性。
要访问和使用方向属性,请执行以下操作:
- 在布局编辑器中,选择文本小部件。
- 打开“ 属性”窗口,然后搜索要使用的RTL属性。
要设置属性值,请选择以下选项之一:
- firstStrong:根视图的默认值。第一个强方向字符决定段落方向。如果没有强方向字符,则段落方向是视图的已解析布局方向。
- anyRtl:如果段落方向包含任何强 RTL字符,则它是RTL; 否则,如果它包含任何强LTR字符,则为LTR。如果两者都没有,则段落方向是视图的已解析布局方向。
- ltr:段落方向是LTR。
- rtl:段落方向是RTL。
- locale:段落方向来自系统区域设置。
- 继承:默认。使用父级中设置的方向。
注意:强方向字符有自己的预定义方向,例如大多数字母和音节字符,非欧洲和非阿拉伯数字,汉字表意文字和仅针对这些脚本的标点字符。
- 要查看反转的文本和布局,请运行该应用程序。
Pseudolocales
伪语言是一种模拟语言环境,旨在承担在翻译应用程序时导致UI,布局,RTL和其他翻译问题的语言特征。Pseudolocales提供即时和自动翻译,可以用英语阅读所有可本地化的消息。这使您可以在源代码中捕获不可翻译的消息。
有关如何使用伪聚合的信息,请参阅 使用Pseudolocales测试您的应用程序。
3.
使用注解改进代码检查
使用代码检查工具(例如 Lint)可以帮助您找到问题并改进代码,不过,检查工具只能推断这么多信息。例如,Android 资源 ID 使用 int
标识字符串、图形、颜色和其他资源类型,因此,检查工具无法告诉您何时指定字符串资源以及应在什么地方指定颜色。在这种情况下,您的应用可能无法正确渲染或根本无法运行,即使使用代码检查也是如此。
您可以使用注解向 Lint 之类的代码检查工具提供提示,帮助检测这些更细微的代码问题。您可以将注解作为元数据标记附加至变量、参数和返回值,用于检查方法返回值、传递的参数以及本地变量和字段。如果与代码检查工具搭配使用,注解可以帮助您检测问题,例如 null 指针异常和资源类型冲突。
Android 通过注解支持库支持各种注解。您可以通过 android.support.annotation
软件包获取该库。
向您的项目添加注解
要在您的项目中启用注解,请向您的库或应用添加 support-annotations
依赖项。添加的任何注解都会在您随后运行代码检查或 lint
任务时进行检查。
添加支持注解库依赖项
支持注解库是 Android 支持库的一部分。要向您的项目添加注解,您必须下载支持存储库并向 build.gradle
文件中添加 support-annotations
依赖项。
- 打开 SDK 管理器,方法是点击工具栏中的 SDK Manager 或者选择 Tools > Android > SDK Manager。
- 点击 SDK Tools 标签。
- 展开 Support Repository 并选中 Android Support Repository 复选框。
- 点击 OK。
- 继续安装向导的说明操作,安装软件包。
- 将以下代码行添加到
build.gradle
文件的dependencies
块中,向您的项目添加support-annotations
依赖项:
dependencies { compile 'com.android.support:support-annotations:24.2.0' } 您下载的库版本可能较高,因此,确保您在此指定的值与第 3 步中的版本匹配。 - 在显示的工具栏或同步通知中,点击 Sync Now。
如果您在自己的库模块中使用注解,注解将作为 Android 归档 (AAR) 工件的一部分以 XML 格式添加到 annotations.zip
文件中。添加 support-annotations
依赖项不会为您的库的任何下游用户引入依赖关系。
如果想要在未使用适用于 Gradle 的 Android 插件但使用 Gradle Java 插件的 Gradle 模块中使用注解(com.android.application
或 com.android.library
),您必须明确添加 SDK 存储库,因为无法从 JCenter Java 存储库获得 Android 支持库:
repositories {
jcenter()
maven { url '<your-SDK-path>/extras/android/m2repository' }
}
注:如果您使用 appcompat
库,则无需添加 support-annotations
依赖项。因为 appcompat
库已经依赖注解库,您可以访问相关注解。
要查看支持存储库中包含的完整注解列表,请查看支持注解库参考,或者使用自动填充功能显示 import android.support.annotation.
语句的可用选项。
运行代码检查
要从 Android Studio 启动代码检查(包含验证注解和自动 Lint 检查),请从菜单栏中选择 Analyze > Inspect Code。Android Studio 将显示冲突消息,在您的代码与注解冲突的地方标记潜在问题并建议可能的解决方法。
您还可以通过使用命令行运行 lint
任务来强制注解。尽管这对标记持续集成服务器遇到的问题可能有用,请注意,lint
任务并不会强制 nullness 注解(只有 Android Studio 会强制)。如需了解有关启用和运行 Lint 检查的详细信息,请参阅使用 Lint 改进您的代码。
请注意,尽管注解冲突会生成警告,但这些警告不会阻止您的应用编译。
Nullness 注解
添加 @Nullable
和 @NonNull
注解,以检查给定变量、参数或返回值的 nullness。@Nullable
注解指示可以为 null 的变量、参数或返回值,而 @NonNull
则指示不可为 null 的变量、参数或返回值。
例如,如果一个包含 null 值的局部变量作为已附加 @NonNull
注解的参数传递到某个方法,则构建代码将生成一个指示非 null 冲突的警告。另一方面,对于通过 @Nullable
标记的方法的结果,如果不先检查其是否为 null,那么在尝试引用它时将生成 nullness 警告。只有在每次使用方法时都应明确检查是否为 null 的情况下,才应对方法返回值使用 @Nullable
。
下面的示例会将 @NonNull
注解附加到 context
与 attrs
参数,以检查传递的参数值是否不为 null。它还会检查 onCreateView()
方法本身是否不会返回 null:
import android.support.annotation.NonNull;
...
/** Add support for inflating the <fragment> tag. **/
@NonNull
@Override
public View onCreateView(String name, @NonNull Context context,
@NonNull AttributeSet attrs) {
...
}
...
Nullability 分析
Android Studio 支持通过运行 nullability 分析,在您的代码中自动推断和插入 nullness 注解。Nullability 分析会在您代码的整个方法层次结构中扫描协定类,以检测:
- 可返回 Null 的调用方法
- 不会返回 Null 的方法
- 可以为 Null 的变量,如字段、局部变量和参数
- 不能为 Null 值的变量,如字段、局部变量和参数
然后,此分析将自动在已检测到的位置插入相应的 null 注解。
要在 Android Studio 中运行 nullability 分析,请选择 Analyze > Infer Nullity。Android Studio 会在代码中已检测到的位置插入 Android @Nullable
和 @NonNull
注解。运行 null 分析后,最好验证一下插入的这些注解。
注:添加 nullness 注解时,自动填充可能会建议 IntelliJ @Nullable
和 @NotNull
注解而不是 Android null 注解,并且可能会自动导入相应的库。不过,Android Studio Lint 检查器仅会查找 Android null 注解。验证您的注解时,请确认您的项目使用 Android null 注解,以便 Lint 检查器可以在代码检查期间正确通知您。
资源注解
验证资源类型可能非常有用,因为 Android 对资源(例如可绘制对象和字符串资源)的引用以整型形式传递。需要参数来引用特定类型资源(例如可绘制对象)的代码可以作为预计的引用类型 int
传入,不过实际将引用不同类型的资源,例如 R.string
资源。
例如,添加 @StringRes
注解,以检查资源参数是否包含 R.string
引用,如下面所示:
public abstract void setTitle(@StringRes int resId) { … }
在代码检查期间,如果参数中未传入 R.string
引用,注解将生成警告。
其他资源类型的注解(例如 @DrawableRes
、@DimenRes
、@ColorRes
和 @InterpolatorRes
)可以使用相同的注解格式添加并在代码检查期间运行。如果您的参数支持多种资源类型,您可以在给定参数上添加更多注解。使用 @AnyRes
能够指示注解的参数可为任意类型的 R
资源。
尽管您可以使用 @ColorRes
指定某个参数应为颜色资源,但是颜色整型(RRGGBB
或 AARRGGBB
格式)无法识别为颜色资源。请改用 @ColorInt
注解指示某个参数必须为颜色整型。构建工具会标记不正确代码,该代码会将颜色资源 ID(例如 android.R.color.black
)而不是颜色整型传递到已注解方法。
线程注解
线程注解可以检查某个方法是否从特定类型的线程调用。支持以下线程注解:
注:构建工具会将 @MainThread
和 @UiThread
注解视为可互换,因此,您可以从 @MainThread
方法调用 @UiThread
方法,反之亦然。不过,如果系统应用在不同线程上带有多个视图,UI 线程可与主线程不同。因此,您应使用 @UiThread
标注与应用的视图层次结构关联的方法,使用 @MainThread
仅标注与应用生命周期关联的方法。
如果某个类中的所有方法具有相同的线程要求,您可以向该类添加一个线程注解,以验证该类中的所有方法是否均从相同类型的线程调用。
线程注解的一个常见用途是验证 AsyncTask 类中的方法替换,因为此类会执行后台操作并将结果仅发布到 UI 线程上。
值约束注解
使用 @IntRange
、@FloatRange
和 @Size
注解可以验证传递的参数的值。在应用到用户可能弄错其范围的参数时,@IntRange
和 @FloatRange
都非常有用。
@IntRange
注解可以验证整型或长整型参数值是否位于指定范围内。下面的示例可以确保 alpha
参数包含 0 至 255 范围内的整数值:
public void setAlpha(@IntRange(from=0,to=255) int alpha) { … }
@FloatRange
注解可以检查浮点或双整型参数值是否位于指定的浮点值范围内。下面的示例可以确保 alpha
参数包含 0.0 至 1.0 的浮点值:
public void setAlpha(@FloatRange(from=0.0, to=1.0) float alpha) {...}
@Size
注解可以检查集合或数组的大小,以及字符串的长度。@Size
注解可用于验证以下质量:
- 最小大小(例如
@Size(min=2)
) - 最大大小(例如
@Size(max=2)
) - 确切大小(例如
@Size(2)
) - 表示大小必须为此倍数的数字(例如
@Size(multiple=2)
)
例如,@Size(min=1)
可以检查某个集合是否不为空,@Size(3)
可以验证某个数组是否刚好包含三个值。下面的示例可以确保 location
数组至少包含一个元素:
int[] location = new int[3];
button.getLocationOnScreen(@Size(min=1) location);
权限注解
使用 @RequiresPermission
注解可以验证方法调用方的权限。要检查有效权限列表中是否存在某个权限,请使用 anyOf
属性。要检查是否存在一组权限,请使用 allOf
属性。下面的示例会标注 setWallpaper()
方法,以确保方法的调用方拥有 permission.SET_WALLPAPERS
权限:
@RequiresPermission(Manifest.permission.SET_WALLPAPER)
public abstract void setWallpaper(Bitmap bitmap) throws IOException;
此示例要求 copyFile()
方法的调用方同时具有外部存储空间的读写权限:
@RequiresPermission(allOf = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE})
public static final void copyFile(String dest, String source) {
...
}
对于 intent 权限,请将权限要求添加到定义 intent 操作名称的字符串字段上:
@RequiresPermission(android.Manifest.permission.BLUETOOTH)
public static final String ACTION_REQUEST_DISCOVERABLE =
"android.bluetooth.adapter.action.REQUEST_DISCOVERABLE";
对于您需要单独读写权限的内容提供程序的权限,请在 @RequiresPermission.Read
或 @RequiresPermission.Write
注解中包含每个权限要求:
@RequiresPermission.Read(@RequiresPermission(READ_HISTORY_BOOKMARKS))
@RequiresPermission.Write(@RequiresPermission(WRITE_HISTORY_BOOKMARKS))
public static final Uri BOOKMARKS_URI = Uri.parse("content://browser/bookmarks");
间接权限
如果权限依赖于提供给方法参数的特定值,请对参数本身使用 @RequiresPermission
,而不用列出具体权限。例如,startActivity(Intent)
方法会对传递到方法的 intent 使用间接权限:
public abstract void startActivity(@RequiresPermission Intent intent, @Nullable Bundle) {...}
在您使用间接权限时,构建工具将执行数据流分析以检查传递到方法的参数是否具有任何 @RequiresPermission
注解。随后,它们会对方法本身强制参数的任何现有注解。在 startActivity(Intent)
示例中,当一个不具有相应权限的 intent 传递到方法时,Intent
类中的注解会针对 startActivity(Intent)
的无效使用生成警告,如图 1 中所示。
图 1. startActivity(Intent)
方法上从间接权限注解生成的警告。
构建工具会在 startActivity(Intent)
上从 Intent
类中相应 intent 操作名称的注解生成警告:
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
@RequiresPermission(Manifest.permission.CALL_PHONE)
public static final String ACTION_CALL = "android.intent.action.CALL";
如果需要,在标注方法的参数时,您可以将 @RequiresPermission
替换为 @RequiresPermission.Read
和/或 @RequiresPermission.Write
。不过,间接权限 @RequiresPermission
不应与读取或写入权限注解搭配使用。
返回值注解
使用 @CheckResult
注解可以验证实际使用的是方法的结果还是返回值。添加注释来阐明可能令人困惑的方法的结果,而不是使用 @CheckResult
标注每个非空方法。例如,新 Java 开发者经常误认为 <String>.trim()
会移除原始字符串中的空格。使用 @CheckResult
标注方法会在调用方未对方法返回值作任何处理的地方标记 <String>.trim()
的使用。
下面的示例会标注 checkPermissions()
方法,以确保实际引用方法的返回值。它还会将 enforcePermission()
方法指定为要向开发者建议的替换方法:
@CheckResult(suggest="#enforcePermission(String,int,int,String)")
public abstract int checkPermission(@NonNull String permission, int pid, int uid);
CallSuper 注解
使用 @CallSuper
注解可以验证替换方法是否会调用方法的超类实现。下面的示例会标注 onCreate()
方法,以确保任何替换方法实现都会调用 super.onCreate()
:
@CallSuper
protected void onCreate(Bundle savedInstanceState) {
}
Typedef 注解
使用 @IntDef
和 @StringDef
注解,以便能够创建整型和字符串集的枚举注解来验证其他类型的代码引用。Typedef 注解可以确保特定参数、返回值或字段引用特定的常量集。它们还可以完成代码以自动提供允许的常量。
Typedef 注解使用 @interface
声明新的枚举注解类型。@IntDef
和 @StringDef
注解以及 @Retention
可以标注新注解,并且为定义枚举的类型所必需。@Retention(RetentionPolicy.SOURCE)
注解可以告知编译器不将枚举的注解数据存储在 .class
文件中。
下面的示例说明了创建注解的具体步骤,此注解可以确保作为方法参数传递的值引用一个定义的常量:
import android.support.annotation.IntDef;
...
public abstract class ActionBar {
...
// Define the list of accepted constants and declare the NavigationMode
annotation
@Retention(RetentionPolicy.SOURCE)
@IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS})
public @interface NavigationMode {}
// Declare the constants
public static final int NAVIGATION_MODE_STANDARD = 0;
public static final int NAVIGATION_MODE_LIST = 1;
public static final int NAVIGATION_MODE_TABS = 2;
// Decorate the target methods with the annotation
@NavigationMode
public abstract int getNavigationMode();
// Attach the annotation
public abstract void setNavigationMode(@NavigationMode int mode);
在您构建此代码时,如果 mode
参数不引用一个定义的常量(NAVIGATION_MODE_STANDARD
、NAVIGATION_MODE_LIST
或 NAVIGATION_MODE_TABS
),则会生成警告。
您还可以组合 @IntDef
和 @IntRange
,以指示整型可以是给定的常量集或某个范围内的值。
允许将常量与标志相结合
如果用户可以将允许的常量与标志(例如,|
、&
和 ^
,等等)相结合,则您可以通过 flag
属性定义一个注解,以检查某个参数或返回值是否会引用有效模式。下面的示例将使用一组有效的 DISPLAY_
常量创建 DisplayOptions
注解:
import android.support.annotation.IntDef;
...
@IntDef(flag=true, value={
DISPLAY_USE_LOGO,
DISPLAY_SHOW_HOME,
DISPLAY_HOME_AS_UP,
DISPLAY_SHOW_TITLE,
DISPLAY_SHOW_CUSTOM
})
@Retention(RetentionPolicy.SOURCE)
public @interface DisplayOptions {}
...
在您使用注解标志构建代码时,如果经过修饰的参数或返回值不引用有效模式,则将生成警告。
代码可访问性注解
使用 @VisibleForTesting
和 @Keep
注解可以表示方法、类或字段的可访问性。
@VisibleForTesting
注解指示一个代码块的可见性是否高于让代码变得可测试所需要的水平。
@Keep
注解可以确保如果在构建时缩减代码,标注的元素不会移除。它一般会添加到通过反射访问的方法和类中,以阻止编译器将代码视为未使用。
4.
工具属性参考
Android Studio支持tools
命名空间中的各种XML属性,这些属性支持设计时功能(例如,在片段中显示哪种布局)或编译时行为(例如应用于XML资源的缩小模式)。构建应用程序时,构建工具会删除这些属性,因此不会影响APK大小或运行时行为。
要使用这些属性,请将tools
命名空间添加到您要使用它们的每个XML文件的根元素,如下所示:
< RootTag xmlns:android = “http://schemas.android.com/apk/res/android” xmlns:tools = “http://schemas.android.com/tools” >
错误处理属性
以下属性有助于抑制lint警告消息。
tools:ignore
用于:任何元素
使用者:Lint
此属性接受以逗号分隔的lint问题ID列表,您希望工具在此元素或其任何后代上忽略这些ID。
例如,您可以告诉工具忽略MissingTranslation
错误:
<string name="show_all_apps" tools:ignore="MissingTranslation">All</string>
tools:targetApi
用于:任何元素
使用者:Lint
此属性与@TargetApi
Java代码中的注释相同 :它允许您指定支持此元素的API级别(作为整数或代码名称)。
这告诉工具您认为此元素(以及任何子元素)将仅在指定的API级别或更高级别上使用。这会阻止lint警告您,如果该元素或其属性在您指定为您的API级别上不可用minSdkVersion
。
例如,您可以使用它,因为 GridLayout
它仅在API级别14及更高级别上可用,但您知道此布局不用于任何较低版本:
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:targetApi="14" >
但是,您应该GridLayout
从 支持库中使用。
tools:locale
用于: <resources>
使用者:Lint,Android Studio编辑器
这告诉工具给定<resources>
元素中的资源的默认语言/语言环境是什么(因为工具否则假定为英语),以避免来自拼写检查器的警告。该值必须是有效的 区域设置限定符。
例如,您可以将其添加到您的values/strings.xml
文件(默认字符串值),以指示用于默认字符串的语言是西班牙语而不是英语:
<resources xmlns:tools="http://schemas.android.com/tools"
tools:locale="es">
设计时视图属性
以下属性定义仅在Android Studio布局预览中可见的布局特征。
tools:
代替 android:
用于: <View>
使用者:Android Studio布局编辑器
您可以使用tools:
前缀而不是Android框架中的android:
任何<View>
属性在布局预览中插入示例数据。如果在运行时之前未填充属性的值,但您希望在布局预览中预先查看效果,则此功能非常有用。
例如,如果android:text
属性值是在运行时设置的,或者您希望看到布局的值不同于默认值,则可以添加 tools:text
以仅为布局预览指定一些文本。
图1.该tools:text
属性将“Google Voice”设置为布局预览的值
您可以添加android:
命名空间属性(在运行时使用)和匹配tools:
属性(仅在布局预览中覆盖运行时属性)。
您也可以使用tools:
属性来取消设置的属性只为布局预览。例如,如果您FrameLayout
有多个子项但想要在布局预览中只看到一个子项,则可以将其中一个设置为在布局预览中不可见,如下所示:
<Button android:id = “@ + id / button” android:layout_width = “wrap_content” android:layout_height = “wrap_content” android:text = “First” /> <Button android:id = “@ + id / button2” android :layout_width = “wrap_content” android:layout_height = “wrap_content” android:text = “Second” 工具:visibility = “invisible” />
在设计视图中使用布局编辑器时,“ 属性”窗口还允许您编辑某些设计时视图属性。每个设计时属性都用属性名称旁边的扳手图标表示,以区别于同名的真实属性。
tools:context
用于:任何根 <View>
使用者:Lint,Android Studio布局编辑器
此属性声明默认情况下此布局与哪个活动相关联。这使得编辑器或布局预览中的功能需要活动知识,例如布局主题在预览中应该是什么以及onClick
当您从quickfix中进行处理时插入处理程序的位置(图2)。
图2.onClick
属性的Quickfix 仅在您设置时才有效tools:context
您可以使用与清单文件中相同的点前缀指定活动类名称(不包括完整的包名称)。例如:
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity" >
提示: 您还可以从“ 布局编辑器”工具栏中选择布局预览的主题 。
tools:itemCount
用于: <RecyclerView>
使用者:Android Studio布局编辑器
对于给定的RecyclerView
,此属性指定布局编辑器应在“ 预览”窗口中呈现的项目数 。
例如:
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:itemCount="3"/>
tools:layout
用于: <fragment>
使用者:Android Studio布局编辑器
此属性声明您希望布局预览在片段内绘制的布局(因为布局预览无法执行通常应用布局的活动代码)。
例如:
<fragment android:name="com.example.master.ItemListFragment"
tools:layout="@layout/list_content" />
tools:listitem / tools:listheader / tools:listfooter
用于:( <AdapterView>
和子类一样<ListView>
)
使用者:Android Studio布局编辑器
这些属性指定在列表的项目,页眉和页脚的布局预览中显示的布局。布局中的任何数据字段都填充数字内容,例如“项目1”,以便列表项不重复。
例如:
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:listitem="@layout/sample_list_item"
tools:listheader="@layout/sample_list_header"
tools:listfooter="@layout/sample_list_footer" />
注意:这些属性ListView
在Android Studio 2.2中不起作用,但这已在2.3(问题215172)中修复。
tools:showIn
用于:<View>
由布局引用的 任何根<include>
使用者:Android Studio布局编辑器
此属性允许您指向将此布局用作包含的布局,因此您可以预览(和编辑)此文件,因为它在嵌入其父布局时显示。
例如:
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:text="@string/hello_world"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:showIn="@layout/activity_main" />
现在,布局预览显示TextView
布局内显示的 activity_main
布局。
tools:menu
用于:任何根 <View>
使用者:Android Studio布局编辑器
此属性指定布局预览应在应用栏中显示的菜单 。该值可以是一个或多个菜单ID,以逗号分隔(没有@menu/
或任何此类ID前缀且没有.xml
扩展名)。例如:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:menu="menu1,menu2" />
tools:minValue / tools:maxValue
用于: <NumberPicker>
使用者:Android Studio布局编辑器
这些属性设置NumberPicker
视图的最小值和最大值 。
例如:
<NumberPicker xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/numberPicker"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:minValue="0"
tools:maxValue="10" />
tools:openDrawer
用于: <DrawerLayout>
使用者:Android Studio布局编辑器
此属性允许您在布局编辑器DrawerLayout
的“ 预览”窗格中打开a 。您还可以通过传递以下值之一来修改布局编辑器呈现布局的方式:
不变 | 值 | 描述 |
---|---|---|
结束 | 800005 | 将对象推送到其容器的末尾,而不是更改其大小。 |
剩下 | 3 | 将对象推到其容器的左侧,而不是更改其大小。 |
对 | 五 | 将对象推到其容器的右侧,而不是更改其大小。 |
开始 | 800003 | 将对象推送到其容器的开头,而不是更改其大小。 |
例如:
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:openDrawer="start" />
"@tools:sample/*"
资源
适用于:支持UI文本或图像的任何视图。
使用者:Android Studio布局编辑器
此属性允许您将占位符数据或图像注入视图。例如,如果要测试布局在文本中的行为方式,但尚未为应用程序确定最终的UI文本,则可以使用占位符文本,如下所示:
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="@tools:sample/lorem" />
下表描述了可以注入布局的占位符数据的类型。
属性值 | 占位符数据的说明 |
---|---|
@tools:sample/full_names | 是随机从组合产生的全名 @tools:sample/first_names 和@tools:sample/last_names 。 |
@tools:sample/first_names | 常见的名字。 |
@tools:sample/last_names | 常用的姓氏。 |
@tools:sample/cities | 来自世界各地的城市名称。 |
@tools:sample/us_zipcodes | 随机生成的美国邮政编码。 |
@tools:sample/us_phones | 随机生成的电话号码格式如下: (800) 555-xxxx 。 |
@tools:sample/lorem | 来自拉丁语的占位符文本。 |
@tools:sample/date/day_of_week | 指定格式的随机日期和时间。 |
@tools:sample/date/ddmmyy | |
@tools:sample/date/mmddyy | |
@tools:sample/date/hhmm | |
@tools:sample/date/hhmmss | |
@tools:sample/avatars | 矢量drawables,您可以用作配置文件头像。 |
@tools:sample/backgrounds/scenic | 您可以用作背景的图像。 |
资源缩减属性
以下属性允许您启用严格引用检查,并声明在使用资源收缩时是保留还是丢弃某些资源 。
为了实现资源的萎缩,设置shrinkResources
属性为true
您的build.gradle
文件(旁边minifyEnabled
代码萎缩)。例如:
android {
...
buildTypes {
release {
shrinkResources true
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-rules.pro'
}
}
}
tools:shrinkMode
用于: <resources>
使用者:使用资源缩减构建工具
此属性允许您指定构建工具是否应使用“安全模式”(保护安全并保留所有明确引用的资源以及可能通过调用动态 引用的资源Resources.getIdentifier()
)或“严格模式”(仅保留资源)在代码或其他资源中明确引用)。
默认是使用安全模式(shrinkMode="safe"
)。要改为使用严格模式,请添加shrinkMode="strict"
到<resources>
标记,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
tools:shrinkMode="strict" />
启用严格模式时,您可能需要使用tools:keep
以保留已删除但实际需要的资源,并用于 tools:discard
显式删除更多资源。
有关更多信息,请参阅 缩小资源。
tools:keep
用于: <resources>
使用者:使用资源缩减构建工具
使用资源收缩来删除未使用的资源时,此属性允许您指定要保留的资源(通常是因为它们在运行时以间接方式引用,例如通过将动态生成的资源名称传递给 Resources.getIdentifier()
)。
要使用,请在资源目录(例如,at res/raw/keep.xml
)中使用<resources>
标记创建XML文件, 并将每个资源指定tools:keep
为以逗号分隔的列表保留在属性中。您可以将星号字符用作通配符。例如:
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
tools:keep="@layout/used_1,@layout/used_2,@layout/*_3" />
有关更多信息,请参阅 缩小资源。
tools:discard
用于: <resources>
使用者:使用资源缩减构建工具
当使用资源收缩来去除未使用的资源时,此属性允许您指定要手动丢弃的资源(通常是因为资源被引用但不会影响您的应用,或者因为Gradle插件错误地推断出资源被引用)。
要使用,请在资源目录(例如,at res/raw/keep.xml
)中使用<resources>
标记创建XML文件, 并将每个资源指定tools:discard
为以逗号分隔的列表保留在属性中。您可以将星号字符用作通配符。例如:
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
tools:discard="@layout/unused_1" />
有关更多信息,请参阅 缩小资源。