上图是山东省聊城市东昌湖一角,古城墙、古院落 再配上护城河,一切都显得韵味十足。
一、tools 命名空间是啥?在哪里有?
在Android Studio 中,我们创建一个 xml 布局文件之后,通常在自动生成的代码中,会有一个 tools 命名空间: xmlns:tools="http://schemas.android.com/tools"
。之前一直不知道是干嘛用的,从来没有用过,然后要么手动删除,要么格式化代码的时候就自动把它删除了。直到今天翻看文档时才发现,这玩意儿竟然有大用途!
二、tools 命名空间的作用有哪些?
根据官方文档描述,根据其属性的功能类别,大致有三种主要功能:
- xml中的错误处理
- xml 预览
- 资源压缩
说的通俗一点就是:
- 减少或者避免黄线提示,让代码更清爽,让编译少报错
- 让预览界面更灵活,可以随心所欲的定制预览视图
- 压缩资源文件,降低APK体积。
三、tools 命名空间属性功能详解
该部分内容是基于官方文档的总结整理,由于个人水平有限,理解可能会有偏差,欢迎指正
(一)、xml 中的错误处理属性
1、tools:ignore
代码语言:javascript复制xml中的任意元素
示例1: Lint 检查时默认语言为 英文,如果在 xml 中有中文,就会报 MissingTranslation 错误,我们加上 tools:ignore 之后即可避免。
代码语言:javascript复制<string name="show_all_apps" tools:ignore="MissingTranslation">All</string>
示例2:
2、tools:targetApi
. | 说明 |
---|---|
应用范围 | xml的任意元素 |
作用对象 | Lint |
具体作用 | 同 java 代码中的 @TargetApi 注解, 指明某个控件只在指定的API 及更高的版本中生效。这样,在使用 Lint 检测时就不会因 minSdkVersion 低于控件出现的版本而报错。 |
取值说明 | API 版本号对应的 int值 |
示例:
代码语言:javascript复制<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:targetApi="14" >
3、 tools:locale
. | 说明 |
---|---|
应用范围 | |
作用对象 | Lint, Android Studio editor |
具体作用 | 指明 resources 中元素的语言类型,避免拼写检查或者Lint 检查时报错。这两者中默认的语言类型时英文 es |
取值说明 |
示例: 我们在 values/strings.xml
中指明元素的语言版本。
<resources xmlns:tools="http://schemas.android.com/tools" tools:locale="es">
(二)、xml视图预览相关属性
以下属性在xml中定义之后,只在预览时会展示,正式部署之后并不会展示。 类似于DataBindg中引用字符串资源时的default属性。
1、用 tools:xxxx 替代 android:xxxx
. | 说明 |
---|---|
应用范围 | view |
作用对象 | Android Studio布局编辑器 |
具体作用 | 将view的任意属性值的 android 前缀替换为 tools 之后,就可以实现预览效果。以tools 为命名空间的属性值只在预览时有效。 另外,在预览时,如果同时有 tools:xxx 和 android:xxx ,则优先展示 tools:xxx 的预览效果, 可参考示例代码2 |
取值说明 | 具体取值以view的属性取值为准。 |
示例代码1: 预览时展示指定文本
代码语言:javascript复制<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="欢迎关注 CnPeng 公众号"
/>
示例代码2: tools:text 和 android:text 同时存在,在预览时会优先展示 tools:text
代码语言:javascript复制<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="这些在预览时展示,并会在预览时优先于 android:text 展示"
android:text="这些在部署之后会展示"
/>
2、tools:context
代码语言:javascript复制xml 中的根布局
示例代码: 先声明关联的activity,然后直接写 onclick 方法名,然后按下自动完成代码的快捷键,就会提示在对应的activity中创建该方法。
3、tools:itemCount
. | 说明 |
---|---|
应用范围 | |
作用对象 | Android Studio 布局编辑器 |
具体作用 | 在 节点中设置该属性之后,会指定在预览界面中绘制/展示几个条目 |
取值说明 | int 类型数值 |
示例代码: 预览界面展示 4个 条目
4、tools:layout
. | 说明 |
---|---|
应用范围 | < fragment> |
作用对象 | Android Studio 布局编辑器 |
具体作用 | 声明在预览时将哪个布局文件填充到该Fragment |
取值说明 | 布局id 的引用值 |
示例代码: 在预览时将 testlayout 这个布局文件填充到fragment。 testlayout的布局中包含一个RecyclerView,并通过itemCount设置的预览时展示的条数为4(参考tools:itemCount)
5、tools:listitem 、 tools:listheader 、 tools:listfooter
. | 说明 |
---|---|
应用范围 | 及其子类,如 |
作用对象 | Android Studio 布局编辑器 |
具体作用 | 指明 AdapterView在预览界面中所展示的 条目、头布局、脚步局 |
取值说明 | 布局文件的引用 |
示例代码:这里略微有点尴尬,listfooter 在预览时并没有展示出来,不知道是不是我操作的姿势不对
item_spinner.xml
代码语言:javascript复制<?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:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:layout_width="@dimen/dp50"
android:layout_height="@dimen/dp50"
android:src="@drawable/logo"
tools:ignore="ContentDescription"/>
<!--ignore 后面根由多个错误id时,用逗号分隔 ; -->
<TextView
android:id="@ id/tv_item_suspendRv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="@dimen/dp10"
android:gravity="center_vertical"
android:text="abc"
tools:ignore="HardcodedText,RtlHardcoded"/>
<!--使用 tools:text 设置预览文本-->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="这是设置的预览文本"/>
</LinearLayout>
注意如果 条目布局中有 TextView及其子类控件
- 如果设置了 tools:text , 在预览时会优先展示该值;
- 如果没有设置 tools:text ,但设置了 android:text , 在预览时就会展示android:text 的属性值;
- 如果都没有设置,则会默认使用 item1、item2 填充到 TextView中作为预览文本
6、 tools:showIn
. | 说明 |
---|---|
应用范围 | 所有 的根节点(即 布局文件的根节点) |
作用对象 | Android Studio 布局编辑器 |
具体作用 | 声明该布局文件将会被哪个布局通过 引用。声明之后,在对应的文件中不要忘了用 引用 |
取值说明 | 布局文件的引用。 |
示例代码:
testlayout2.xml 将会被 testlayout 引用。
testlayout2.xml
代码语言:javascript复制<?xml version="1.0" encoding="utf-8"?>
<TextView
android:id="@ id/testFragment"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:showIn="@layout/testlayout"
tools:text="预览文本">
</TextView>
testlayout.xml
代码语言:javascript复制<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="@layout/testlayout2"/>
</LinearLayout>
通过这种方式我们在确认该布局文件在哪里使用了的时候就比较方便了。但是:
如果该布局文件被多处 include 引用时,tools:showIn 该怎么写呢?哪位朋友知道烦请告知。
7、 tools:menu
代码语言:javascript复制布局文件的根节点( Anyroot <View>
)
注意:按照官方文档的说明,可以传入多个 menu id 。但是实际测试时发现,传入多个时右上角并没有什么不同的显示。
8、 tools:minValue / tools:maxValue
. | 说明 |
---|---|
应用范围 | |
作用对象 | Android Studio 布局编辑器 |
具体作用 | 为NumberPicker 设置预览时的最小值和最大值 |
取值说明 | int 型数值 |
示例说明:
这个加完之后,并没有看到什么特殊效果。
9、 tools:openDrawer
. | 说明 |
---|---|
应用范围 | |
作用对象 | Android Studio布局编辑器 |
具体作用 | 在预览界面中将 DrawerLayout 打开。 |
取值说明 | end、left、right、start。具体说明,参考下表 |
Constant | Value | Description |
---|---|---|
end | 800005 | Push object to the end of its container, not changing its size. |
left | 3 | Push object to the left of its container, not changing its size. |
right | 5 | Push object to the right of its container, not changing its size. |
start | 800003 | Push object to the beginning of its container, not changing its size. |
注意:1、在需要通过 layoutgravity 声明哪一部分作为侧拉窗口,其取值也是 end、start、left、right。2、tools:openDrawer 的取值必须与侧拉窗口的 layoutgravity 的取值一致
代码示例:
代码语言:javascript复制<?xml version="1.0" encoding="utf-8"?>
<!--此处 openDrawer 的取值必须与侧拉窗口的 layout_gravity 取值一致-->
<android.support.v4.widget.DrawerLayout
android:id="@ id/numberPicker"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:openDrawer="right">
<!--这是未展示侧拉界面时的主体内容-->
<RelativeLayout android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
tools:text="这是主内容"/>
</RelativeLayout>
<!--这是侧拉窗口中的内容。必须通过 layout_gravity 属性声明这是一个侧拉展示的内容-->
<RelativeLayout
android:layout_width="100dp"
android:layout_height="match_parent"
android:layout_gravity="right"
android:background="#f2e67b">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:ems="1"
tools:text="这是要侧拉的东西"/>
</RelativeLayout>
</android.support.v4.widget.DrawerLayout>
10、 "@tools:sample/*" 资源
代码语言:javascript复制所有支持显示 text 或者 image 的view控件( Anyview that supports UI textorimages
)
代码语言:javascript复制Full names that are randomly generated from the combination of @tools:sample/first_names and @tools:sample/last_names.
示例代码:
在下面的预览图中,图标和文本都是直接引用的系统预置的。
(三)、资源压缩相关属性 (Resource shrinking attributes)
下面这些属性,可以让我们在 资源压缩时确定哪些资源可以保留或者丢弃,也可以让我们开启严格模式的资源引用检查。 Thefollowing attributes allow you to enable strict reference checksanddeclare whether to keepordiscard certain resourceswhenusing resource shrinking
开启资源压缩时,在 module 的build.gradle 文件作如下修改:
代码语言:javascript复制android {
buildTypes {
release {
shrinkResources true //开启资源压缩。minifyEnabled 也必须为true,否则编译不通过
minifyEnabled true //开启代码混淆/压缩
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
1、 tools:shrinkMode
代码语言:javascript复制
模式 | 说明 |
---|---|
safe | 保留被显示引用的,或者可能通过Resources.getIdentifier()被动态引用的资源 |
strict | 保留 resources 或者 代码中 被显示引用的资源 |
默认是 safe 模式 (即 shrinkMode="safe"
). 如果想使用 strict 模式,需要在节点中显示声明 shrinkMode="strict"
,具体如下:
<?xml version="1.0" encoding="utf-8"?>
<resources
xmlns:tools="http://schemas.android.com/tools"
tools:shrinkMode="strict" />
开启 strict 模式之后, 可以使用 tools:keep
保留那些你不想被移除的资源, 或者使用 tools:discard
直接移除资源
2、 tools:keep
. | 说明 |
---|---|
应用范围 | |
作用对象 | 开启了资源压缩的构建工具 |
具体作用 | 使用资源压缩去移除未被使用的资源时,该属性将允许你指明哪些资源可以被保留(比如一些通过Resources.getIdentifier() 间接引用的资源) |
取值说明 | 资源文件的引用 |
使用时,在 resources 目录下创建一个 xml 文件并指定名称,如: res/raw/keep.xml
。创建一个 <resources>
节点,并为 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" />
3、 tools:discard
. | 说明 |
---|---|
应用范围 | |
作用对象 | 开启了资源压缩的构建工具 |
具体作用 | |
取值说明 |
当使用资源压缩工具去除一些无用资源时,使用该属性可以指明一些需要手动删除的资源 (比如:被引用了但是未能生效的资源,或者 Gradle 插件误引用了某些资源被引用).
使用时,在 resources 目录下创建一个 xml 文件并指定名称,如: res/raw/keep.xml
。创建一个 <resources>
节点,并为 tools:keep
赋值,其值代表将被保留的资源,多个资源之间使用逗号间隔,也可以使用 * 作为通配符,示例如下:
<?xml version="1.0" encoding="utf-8"?>
<resources
xmlns:tools="http://schemas.android.com/tools"
tools:discard="@layout/unused_1" />
四、参考资源:
tools 命名空间的官方文档: https://developer.android.google.cn/studio/write/tool-attributes.html
命名空间介绍: http://blog.csdn.net/p106786860/article/details/53943540
注解参考: https://developer.android.google.cn/studio/write/annotations.html?hl=zh-cn
lint 参考: https://developer.android.google.cn/studio/write/lint.html?hl=zh-cn
资源压缩 shrink-resources
: https://developer.android.com/studio/build/shrink-code.html?hl=zh-cn#shrink-resources