原文:Mastering tools namespace on Android
作者:Alexandru Simonescu
譯者:lovexiaov
你可能注意到了 tools 命名空間會出現在許多 Google 提供的樣例布局 XML 文件中尺栖。此命名空間在開發(fā)階段很有用而且不會影響用戶體驗裙品。它包含了幫助我們在 Android Studio 設計視圖中渲染布局的一套方便的屬性前普。
有時這些巧妙的屬性會節(jié)約我們的構建時間羽资。我并不是說會加快構建速度亚情,而是構建相關的 UI 改變會減少渠牲。
<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"/>
tools 命名空間的 URI 是 http://schemas.android.com/tools
畦粮,通常使用 tools
前綴綁定,但你也可以使用任何其他前綴霎桅。
該命名空間中的所有屬性都不會影響運行時或 apk 的大小,它們會在 Gradle 打包應用時被剝離出去讨永。
你可以使用 Android Studio 提供的快捷鍵快速添加 tools 命名空間滔驶。只需輸入 toolsNS
然后按下 TAB
鍵。
值得一提的是截止到寫這篇文章時卿闹,Android Studio 并沒有太多對此 xml 語法補全支持揭糕,不過別擔心,即使 AS 沒有語法提示比原,你仍然可以覆寫 tools
屬性插佛。最簡單的使用方式是:首先書寫基于 android:
命名空間的屬性,然后使用 CMD + D
復制這行量窘,并替換它的前綴(為 tools
)雇寇。
開始使用
當我剛做 Android 開發(fā)時,曾使用 android:text=""
屬性結合一些硬編碼的假文本在 預覽窗口 中查看 TextView 或 EditText 如何顯示蚌铜。但是 Lint 工具會檢查出硬編碼字符串的問題锨侯,最后我只能去定義 strings(來消除此問題),然而這樣做對用戶沒有任何意義冬殃,還使我的 .apk 中包含了沒用的資源囚痴。
(解決上述問題的)技巧是使用 tools:text"@string"
來在預覽窗口中查看預填充了數據的視圖。你會得到類似如下的 xml 代碼:
<TextView
tools:text="Mastering ToolsNs"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
使用以上代碼片段审葬,在設計時你會看到 TextView
中的文字深滚,而在運行時將不會有該屬性存在奕谭。
運行時和設計時的不同屬性
需要注意的是你可以同時使用 android
和 tools
命名空間。tools
命名空間將會用在設計階段而前者會用在運行時痴荐。
有時你希望在運行時開啟某些特性在設計預覽時關閉血柳。Android 文檔展示了 ListView
的例子:
<ListView
android:id="@+id/listView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fastScrollAlwaysVisible="true"
tools:fastScrollAlwaysVisible=""/>
這里你可以看到:在運行時開啟了 fastScrollAlwaysVisible
功能,而在設計時關閉了它生兆。
其實你可以覆蓋所有已存在與 android
命名空間中的屬性难捌,但無法覆蓋自定義屬性。
在XML 中指定目標 API 版本
你可以在 XML 中執(zhí)行 API 級別鸦难,就想在 Java 中使用 @TargetApi
一樣根吁。API 版本可以通過一個整形或它的代號指定。這將避免 Lint 上報版本特定 XML 屬性的問題合蔽。
<TextView
tools:text="Mastering ToolsNs"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:layout_height="match_parent"
tools:targetApi="M"
/>
告知 Lint 你的字符串是正確的
由于 Android Studio / Lint 默認語言是英語击敌,如果你有其他語言的字符串資源,它將會顯示如下的排版警告拴事。
告知 Lint 你本地化資源的技巧:
<resources xmlns:tools="http://schemas.android.com/tools"
tools:locale="es"/>
這樣就不會顯示排版警告了愚争。
在 fragment 和自定義視圖上預覽布局
我發(fā)現這(tools 命名空間)在使用 Fragment
和自定義視圖時非常有用。通過 tools:layout="@layout/your_layout"
屬性你可以設置在預覽窗口中顯示一個布局挤聘。
<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:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MainActivity"
>
<fragment
android:name="com.alexsimo.mastertoolsnamespace.BooksFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:layout="@layout/fragment_books"
/>
</LinearLayout>
上述代碼使用了 tools:layout
屬性來預覽 BooksFragment
布局轰枝,而不用將工程運行在設備或模擬器上。
我們來看一下視圖結構:
activity_main:
<?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:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MainActivity"
>
<fragment
android:name="com.alexsimo.mastertoolsnamespace.BooksFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:layout="@layout/fragment_book"
/>
</LinearLayout>
fragment_book:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/list"
android:name="com.alexsimo.mastertoolsnamespace.BooksFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
app:layoutManager="LinearLayoutManager"
tools:context="com.alexsimo.mastertoolsnamespace.BooksFragment"
tools:listitem="@layout/fragment_book_list_item"
/>
fragment_book_list_item:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
xmlns:tools="http://schemas.android.com/tools"
>
<ImageView
android:layout_width="150dp"
android:layout_height="150dp"
android:id="@+id/imageView"
tools:src="@android:drawable/ic_media_play"
/>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextView
android:id="@+id/id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/text_margin"
android:textAppearance="?attr/textAppearanceListItem"
tools:text="My book title"
/>
<TextView
android:id="@+id/content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/text_margin"
android:textAppearance="?attr/textAppearanceListItem"
tools:text="My book description"
/>
</LinearLayout>
</LinearLayout>
打開 activity_main
的預覽窗口组去,你將會看到如下界面:
預覽列表項布局
如果你比較細心鞍陨,你會看到上面 xml 代碼片段中的 tools:listitem=""
一行。這在預覽列表時會顯示你自定義的列表項而不是默認的 @android:layout/list_content"
从隆。
還有更多相關的屬性诚撵,但是 RecyclerView
沒有 header 或 footer 屬性(這兩個屬性只能用在 ListView
上)。這兩個屬性分別是 tools:listheader
和 tools:listfooter
键闺。
帶父容器上下文的視圖
假如你有一個自定義視圖或可重用的布局會通過 <include>
標簽被用在許多地方寿烟。當設計該視圖時,預覽它在想要包含它的父容器中如何顯示將會很有幫助辛燥。
在上面的 fragment_book_list_item
中筛武,如果我們添加 tools:showIn="@layout/activity_main"
屬性,將可以預覽該列表條目如何顯示在 activity_main 中挎塌。這沒有多大意義徘六,只是為了演示這個概念。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
xmlns:tools="http://schemas.android.com/tools"
tools:showIn="@layout/activity_main"
>
<!-- Remaining views removed -->
</LinearLayout>
預覽界面將類似于這樣:
該特性也依賴于 Android Studio 的版本榴都。截止到寫此文之時待锈,我使用的是 Android Studio v2.1。
關聯 XML 到一個 activity
上
我很確定你已經知道該屬性了嘴高,當我們使用 Android Studio 引導創(chuàng)建一個 Activity
時竿音,在默認生成的 XML 文件中你會找到該屬性 tools:context=".MainActivity"
和屎。如你所知,單個 xml 布局可以被用在多個 Activity 或 Fragment 中春瞬,使用此屬性眶俩,你就告訴了 Android Studio 那個 .java
Activity 類與之相關聯。
這將幫助布局修改這猜測 Activity 的主題快鱼,因為主題曾被定義在 AndroidManifest.xml
文件中。
忽略 Lint 警告
你應該謹慎使用此屬性纲岭,因為忽略 Lint 警告不是一個好主意抹竹。如果 Lint 上報問題,你應該行動起來并修復錯誤和警告止潮。但有時 Lint 給出的是錯誤警告窃判,我們明確知道(或許不知道)我們在做什么。這種情況下你可以使用 tools:ignore=""
喇闸。
想想一下我們有一個圖標找不到它對應的像素密度文件夾袄琳,我們可能會使用 tools:ignore="IconMissingDensityFolder"
忽略 Lint 警告。你可以在 Android 官方文檔 中閱讀更多關于 Lint 的內容燃乍。
帶菜單預覽布局
默認情況下唆樊,定義在 Activity.onCreateOptionsMenu()
中的菜單會被渲染到預覽窗口。但你可以使用 tools:menu="comma separated menu IDs"
覆蓋此菜單刻蟹。我個人不會使用該屬性逗旁,但它可能會對你有用。
設置 Toolbar 導航模式
此屬性很簡單舆瘪!使用 tools:actionBarNavMode="standard|list|tabs"
你可以設置 ActivityBar 的導航模式片效。
收縮資源
Android tools 命名空間中有許多關于收縮資源的屬性,比如 tools:shrinkMode="strict|safe"
英古,tools:keep="@layout|layout_wildcard"
淀衣,tools:discard="@layout/unused"
等,但我不準備在此討論它們召调,因為本文不是討論收縮資源的膨桥,如果你感興趣,可以在 Android Studio 官方文檔中了解更多信息唠叛。