[译] 精通 Android 中的 tools 命名空间

2,755 阅读9分钟
原文链接: www.jianshu.com

原文地址:Mastering tools namespace on Android
原作者:Alexandru Simonescu
译者:lovexiaov

You probably saw in lots of XML layout examples provided by Google, that sometimes appears the tools namespace. This namespace is useful when developing and doesn’t affect the user experience. Are just a set of handy attributes who help rendering layouts in Android’s Studio Design View.

你可能注意到了 tools 命名空间会出现在许多 Google 提供的样例布局 XML 文件中。此命名空间在开发阶段很有用而且不会影响用户体验。它包含了帮助我们在 Android Studio 设计视图中渲染布局的一套方便的属性。

All this tricky attributes can sometimes save us build time. I’m not saying your build will be faster, but your builds related to UI changes can be fewer.

有时这些巧妙的属性会节约我们的构建时间。我并不是说会加快构建速度,而是构建相关的 UI 改变会减少。

The tools namespace full URI is http://schemas.android.com/tools, usually bound to the tools prefix but you can use whatever you want.

tools 命名空间的 URI 是 http://schemas.android.com/tools,通常使用 tools 前缀绑定,但你也可以使用任何其他前缀。

All this attributes doesn’t impact on runtime or apk size, all tools attributes are stripped by gradle when application is packaged.

该命名空间中的所有属性都不会影响运行时或 apk 的大小,它们会在 Gradle 打包应用时被剥离出去。

You can quickly add the tools namespace with the provided shortcut for Android Studio. Just write toolsNS and hit TAB.

你可以使用 Android Studio 提供的快捷键快速添加 tools 命名空间。只需输入 toolsNS 然后按下 TAB 键。


Quick add Tools namespace

Worth mentioning that Android Studio at time of writing this article, doesn’t help too much with the xml syntax completion, so don’t worry, keep writing the tools override even if AS doesn’t gives you syntax hints. The easiest way to use them is to first write the attributes with the android:namespace, duplicate the line with CMD + D and replace the prefix.

值得一提的是截止到写这篇文章时,Android Studio 并没有太多对此 xml 语法补全支持,不过别担心,即使 AS 没有语法提示,你仍然可以覆写 tools 属性。最简单的使用方式是:首先书写基于 android: 命名空间的属性,然后使用 CMD + D 复制这行,并替换它的前缀(为 tools)。


Duplicate and replace namespace

Getting started(开始使用)

When i started developing Android, i used to use the android:text="" attribute with some hardcoded dummy text to see how my TextView or EditText will look on the preview window. But Lint was complaining about hardcoded string and i ended up with defined strings that didn’t deliver nothing to the user and my .apk contained unuseful stuff.

当我刚做 Android 开发时,曾使用 android:text="" 属性结合一些硬编码的假文本在 预览窗口 中查看 TextView 或 EditText 如何显示。但是 Lint 工具会检查出硬编码字符串的问题,最后我只能去定义 strings(来消除此问题),然而这样做对用户没有任何意义,还使我的 .apk 中包含了没用的资源。

The trick is to use the tools:text="@string" to see your views pre filled with data on the preview window. You will end up with similar xml:

(解决上述问题的)技巧是使用 tools:text"@string" 来在预览窗口中查看预填充了数据的视图。你会得到类似如下的 xml 代码:

In the above snippet, at design time you will be able to see the TextView’s text but on runtime that attribute it wont exist.

使用以上代码片段,在设计时你会看到 TextView 中的文字,而在运行时将不会有该属性存在。

Different attributes on runtime and design time(运行时和设计时的不同属性)

Worth note that you can use both android and tools namespaces at same time. The tools namespace will be used at design time and first one at runtime.

需要注意的是你可以同时使用 androidtools 命名空间。tools 命名空间将会用在设计阶段而前者会用在运行时。

Sometimes you want to enable some features on runtime but not on design preview. The Android documentation shows the ListView example:

有时你希望在运行时开启某些特性在设计预览时关闭。Android 文档展示了 ListView 的例子:

There you can see that at runtime, the fastScrollAlwaysVisible is enabled but at design time, is disabled.

这里你可以看到:在运行时开启了 fastScrollAlwaysVisible 功能,而在设计时关闭了它。

Actually you can override any existing attributes from android namespace but with custom attributes it won’t work.

其实你可以覆盖所有已存在与 android 命名空间中的属性,但无法覆盖自定义属性。

Target API versions on XML (在XML 中指定目标 API 版本)

You can target API levels on XML, in the same way as using @TargetApi annotation on Java. The API version can be specified by an integer or as codename. This way Lint it won’t complain about version specific XML attributes.

你可以在 XML 中执行 API 级别,就想在 Java 中使用 @TargetApi 一样。API 版本可以通过一个整形或它的代号指定。这将避免 Lint 上报版本特定 XML 属性的问题。

Tell Lint your string resources are correct(告知 Lint 你的字符串是正确的)

This happens commonly, Android Studio / Lint defaults language is english. If you have for example string resources in other language, it will show some typo warnings as bellow.

由于 Android Studio / Lint 默认语言是英语,如果你有其他语言的字符串资源,它将会显示如下的排版警告。


Language typos warnings

The trick is to tell Lint your resources locale:

告知 Lint 你本地化资源的技巧:

This way it won’t show more typo warnings.

这样就不会显示排版警告了。

Preview layout on fragment and custom views(在 fragment 和自定义视图上预览布局)

I found this specially useful when using Fragment and Custom Views. With the tools:layout="@layout/your_layout" you can set a layout to be shown in the preview window.

我发现这(tools 命名空间)在使用 Fragment 和自定义视图时非常有用。通过 tools:layout="@layout/your_layout" 属性你可以设置在预览窗口中显示一个布局。



    

Above is used the tools:layout attribute to preview the BooksFragment layout, without running the project on a device or emulator.

上述代码使用了 tools:layout 属性来预览 BooksFragment 布局,而不用将工程运行在设备或模拟器上。

Let’s take this view hierarchy:

我们来看一下视图结构:

activity_main:




    

fragment_book:


fragment_book_list_item:




  
  
    
    
  

If i open the preview window for activity_main, i will see the following:

打开 activity_main 的预览窗口,你将会看到如下界面:


Preview list item’s layout(预览列表项布局)

If you were a bit sharp, in the above xml snippet you saw the tools:listitem="" line. While previewing a list is useful to see it with your own custom list item and not the default one @android:layout/list_content".

如果你比较细心,你会看到上面 xml 代码片段中的 tools:listitem="" 一行。这在预览列表时会显示你自定义的列表项而不是默认的 @android:layout/list_content"

There are more related attributes, but as RecyclerView doesn’t have a header or footer property, can only be used with ListView. The mentioned attributes are tools:listheaderand tools:listfooter.

还有更多相关的属性,但是 RecyclerView 没有 header 或 footer 属性(这两个属性只能用在 ListView 上)。这两个属性分别是 tools:listheadertools:listfooter

Views with parent context(带父容器上下文的视图)

Imagine you have a custom view or reusable layout that will be used in many other places using tag. While designing the custom view it may be helpful to preview how it would fit in the parent where is planned to be included.

假如你有一个自定义视图或可重用的布局会通过 标签被用在许多地方。当设计该视图时,预览它在想要包含它的父容器中如何显示将会很有帮助。

With the above fragment_book_list_item if we add tools:showIn="@layout/activity_main", we can preview how this list item would fit in the activity_main. It doesn’t make lot of sense, but just for demonstrating the concept.

在上面的 fragment_book_list_item 中,如果我们添加 tools:showIn="@layout/activity_main" 属性,将可以预览该列表条目如何显示在 activity_main 中。这没有多大意义,只是为了演示这个概念。


    

It would be previewed like this:

预览界面将类似于这样:


It also depends on your Android Studio version. At writing the article i’m using Android Studio v2.1.

该特性也依赖于 Android Studio 的版本。截止到写此文之时,我使用的是 Android Studio v2.1。

Associate XML to an Activity(关联 XML 到一个 activity 上)

I’m sure this attribute you may already know it, by default when creating an Activity using Android’s Studio wizard, in the generated XML file you will find this attribute tools:context=".MainActivity". As you may know, a single xml layout can be used by multiple activities or fragments, using this attribute, you tell Android Studio who’s the associated .java Activity class.

我很确定你已经知道该属性了,当我们使用 Android Studio 引导创建一个 Activity 时,在默认生成的 XML 文件中你会找到该属性 tools:context=".MainActivity"。如你所知,单个 xml 布局可以被用在多个 ActivityFragment 中,使用此属性,你就告诉了 Android Studio 那个 .java Activity 类与之相关联。

This can help the layout editor to guess the activities theme, since themes are used to be defined in the AndroidManifest.xml file.

这将帮助布局修改这猜测 Activity 的主题,因为主题曾被定义在 AndroidManifest.xml 文件中。

Ignore Lint warnings(忽略 Lint 警告)

You should take special care with this attribute, as ignoring Lint warnings is not always a good idea. If Lint complains, you should act and fix the errors and warnings. But sometimes, Lint gives us false warnings, we are aware and we know what we’re doing (or not..). In those cases you can use tools:ignore="".

你应该谨慎使用此属性,因为忽略 Lint 警告不是一个好主意。如果 Lint 上报问题,你应该行动起来并修复错误和警告。但有时 Lint 给出的是错误警告,我们明确知道(或许不知道)我们在做什么。这种情况下你可以使用 tools:ignore=""

Imagine we have an icon who’s missing its density folder, we may ignore the Lint warning with tools:ignore="IconMissingDensityFolder". You can read more about Lint at official Android’s documentation.

想想一下我们有一个图标找不到它对应的像素密度文件夹,我们可能会使用 tools:ignore="IconMissingDensityFolder" 忽略 Lint 警告。你可以在 Android 官方文档 中阅读更多关于 Lint 的内容。

Preview layouts with menus(带菜单预览布局)

By default the menu defined in the Activity.onCreateOptionsMenu() is rendered in the preview window on design mode. But you can override the menu using tools:menu="comma separated menu IDs". This attribute, personally i don’t use it, but may be helpful for you.

默认情况下,定义在 Activity.onCreateOptionsMenu() 中的菜单会被渲染到预览窗口。但你可以使用 tools:menu="comma separated menu IDs" 覆盖此菜单。我个人不会使用该属性,但它可能会对你有用。

Set Toolbar navigation mode(设置 Toolbar 导航模式)

This one is short! Using tools:actionBarNavMode="standard|list|tabs" you can set the ActionBar’s navigation mode.

此属性很简单!使用 tools:actionBarNavMode="standard|list|tabs" 你可以设置 ActivityBar 的导航模式。

Shrink resources(收缩资源)

There are more android tools namespace attributes related with resources shrinking, like tools:shrinkMode="strict|safe", tools:keep="@layout|layout_wildcard", tools:discard="@layout/unused" but i prefer not to talk about them here, since this article is not about shrink resources, if interested you can read more about in Android Studio’s official documentation.

Android tools 命名空间中有许多关于收缩资源的属性,比如 tools:shrinkMode="strict|safe"tools:keep="@layout|layout_wildcard"tools:discard="@layout/unused" 等,但我不准备在此讨论它们,因为本文不是讨论收缩资源的,如果你感兴趣,可以在 Android Studio 官方文档中了解更多信息。

References:(引用:)