我們知道,在 Android 開(kāi)發(fā)過(guò)程中嘀略,我們的數(shù)據(jù)常常來(lái)自于服務(wù)端,只有在運(yùn)行時(shí)才能獲得數(shù)據(jù)展示势就,因此在布局 XML 的編寫(xiě)過(guò)程中纸厉,由于缺少數(shù)據(jù)系吭,我們很難直接看到填充數(shù)據(jù)后的布局效果,那這個(gè)時(shí)候你一般是怎么做的呢颗品?
經(jīng)晨铣撸看到一些小伙伴的做法是在布局文件中臨時(shí)寫(xiě)死一些數(shù)據(jù)來(lái)查看布局展示效果,在查看結(jié)束后躯枢,再手動(dòng)將這些數(shù)據(jù)進(jìn)行刪除则吟。
是不是很麻煩,那我們有沒(méi)有更簡(jiǎn)單點(diǎn)的方案呢锄蹂?
針對(duì)上述的問(wèn)題氓仲,Google 官方其實(shí)早就考慮到了,因此在開(kāi)發(fā)工具中提供了 tools 命名空間的支持败匹。
在布局 XML 文件中使用
tools:
命名空間添加的屬性寨昙,在項(xiàng)目構(gòu)建成 過(guò)程中,tools 屬性會(huì)被構(gòu)建工具自動(dòng)移除掀亩,最終不會(huì)對(duì)構(gòu)建程序產(chǎn)生任何的影響舔哪。
而除去在編寫(xiě)布局時(shí)的預(yù)覽功能外,tools:
命名空間屬性還提供了很多有用的功能槽棍,那么接下來(lái)我們就來(lái)詳細(xì)介紹下 tools 屬性的這些功能捉蚤。
按照官方的定義, tools 屬性劃分為了三種類(lèi)型:
錯(cuò)誤控制屬性(Error handling attributes)
主要用來(lái)幫助我們控制一些由 lint 產(chǎn)生的錯(cuò)誤警告炼七。
tools:ignore
適合于任意元素
我們知道缆巧,在 Android 開(kāi)發(fā)工具中提供了 lint 工具,可以幫助您輕松地識(shí)別并糾正問(wèn)題與結(jié)構(gòu)質(zhì)量的代碼豌拙。
而 lint 中針對(duì)不同的問(wèn)題警告定義了不同的 ID陕悬,該屬性則可以通過(guò)設(shè)置 lint 中對(duì)應(yīng)的問(wèn)題 ID 來(lái)讓 lint 忽略該種警告,同時(shí)也可以通過(guò)逗號(hào)分隔符的方式設(shè)置多個(gè)問(wèn)題 ID 來(lái)忽略多種警告按傅。
例:
<string name="show_all_apps" tools:ignore="MissingTranslation">All</string>
一般在存在多國(guó)語(yǔ)言資源包的情況下捉超, 如果 strings.xml 里某個(gè)String 沒(méi)有給出其他語(yǔ)言版本的翻譯, 那么 lint 會(huì)給出 MissingTranslation 的警告提示唯绍,
而通過(guò) tools:ignore="MissingTranslation"
我們就可以讓 Lint 針對(duì)這條 String 忽略這個(gè)警告拼岳。
再例如我們開(kāi)發(fā)中更常見(jiàn)的一個(gè)問(wèn)題:
在使用 ImageView 標(biāo)簽時(shí),如果不加 android:contentDescription
那么 lint 會(huì)給出 contentDescription 的相關(guān)警告况芒,
此時(shí)惜纸,我們可以通過(guò)給 ImageView 標(biāo)簽添加 tools:ignore="contentDescription"
來(lái)忽略這個(gè)警告。
<ImageView ...
tools:ignore="contentDescription"
/>
tools:targetApi
適用于任何元素
這個(gè)屬性類(lèi)似我們?cè)诖a中使用 @TargetApi
注解
當(dāng)我們使用的組件元素支持的 Android 最低版本大于我們項(xiàng)目所指定的最低版本 minSdkVersion 時(shí), lint 會(huì)給出相應(yīng)的版本警告耐版。
該屬性則可以通過(guò)給指定的布局設(shè)置對(duì)應(yīng)的 API 版本來(lái)通知 lint 忽略警告祠够。
例:
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:targetApi="14" >
如果我們不使用 v4 包下的 GridLayout , 那么 GridLayout 則只支持 API LEVEL 14 以上系統(tǒng),此時(shí)如果我們項(xiàng)目的 minSdkVersion 低于14 椭更,那么 lint 會(huì)給出版本警告
當(dāng)添加了 tools:targetApi="14"
之后哪审,Lint 就會(huì)停止對(duì)應(yīng)的版本警告了。
tools:locale
適用于 <resources>
元素
這個(gè)屬性用來(lái)指定默認(rèn)的資源文件所使用的語(yǔ)言環(huán)境虑瀑,從而避免 Lint 在拼寫(xiě)檢測(cè)的時(shí)候帶來(lái)不必要的警告提示。
默認(rèn)情況下滴须,開(kāi)發(fā)工具會(huì)假設(shè)我們的語(yǔ)言環(huán)境為英語(yǔ)舌狗,因此單詞檢測(cè)器(spell checker)在檢測(cè)過(guò)程中會(huì)對(duì)一些英文字母產(chǎn)生警告。
例如扔水,我的 app_name 叫TRSDK, 默認(rèn)情況下 TRSDK 下會(huì)產(chǎn)生波浪線的警告提示:
此時(shí)如果我通過(guò) tools:locale
設(shè)置默認(rèn)環(huán)境為中文 zh痛侍,那么警告就會(huì)消失了
設(shè)計(jì)時(shí)預(yù)覽屬性(Design-time view attributes)
這類(lèi)屬性主要是針對(duì)于 Android layout 布局的特征屬性的,通過(guò)設(shè)置這類(lèi)屬性可以在 Android Studio 的布局預(yù)覽界面快速預(yù)覽布局展示效果魔市。
tools: instead of android:(可替代任何 android:
開(kāi)頭的屬性)
適用于 <view>
類(lèi)視圖元素
你可以針對(duì)視圖組件的屬性主届,通過(guò)使用 tools :
前綴來(lái)替換 android:
前綴,從而提前在布局預(yù)覽界面預(yù)覽屬性設(shè)置的效果待德。
并且在代碼構(gòu)建的時(shí)候君丁,構(gòu)建工具會(huì)自動(dòng)移除這些屬性,不對(duì)最終打包的 APK 產(chǎn)生任何影響将宪。
例如:
如果 TextView 的數(shù)據(jù)需要在運(yùn)行時(shí)才能獲取绘闷,那我們可以通過(guò)設(shè)置 tool:text
的值,在布局預(yù)覽界面預(yù)覽數(shù)據(jù)填充后的效果较坛,如圖:
我們可以同時(shí)設(shè)置 android: 屬性(運(yùn)行時(shí)才能顯示) 和匹配的 tools: 屬性(只會(huì)在布局預(yù)覽界面顯示)印蔗,構(gòu)建項(xiàng)目時(shí)最終 tools 屬性會(huì)被移除,只以 android: 屬性的值顯示丑勤。
假設(shè) FrameLyout 中有多個(gè)子布局华嘹,并且我們只想預(yù)覽有一個(gè)布局時(shí)的效果,此時(shí)法竞,我們也可以通過(guò)設(shè)置 tools 屬性來(lái)預(yù)覽一個(gè)子布局時(shí)的顯示效果:
<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"
tools:visibility="invisible" />
tools:context
適用于部分 <view>
根布局
該屬性用于設(shè)置布局文件相關(guān)的 Activity耙厚,從而使用開(kāi)發(fā)工具的快速修復(fù)功能( quick fix )時(shí)能自動(dòng)關(guān)聯(lián) Activity 上下文生成對(duì)應(yīng)的代碼。
例如:
<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:orientation="vertical"
tools:context=".MainActivity">
<Button
android:text="Button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/button"
android:layout_weight="1"
android:onClick="onButtonClicked"/>
</LinearLayout>
這里我們給根布局 LinearLayout 設(shè)置了 tools:context = ".MainActivity"爪喘,當(dāng)我們使用 Android Studio 的快速修復(fù)功能時(shí)颜曾,則會(huì)關(guān)聯(lián)相關(guān)的 Activity 進(jìn)行提示:
tools:layout
適用于 <fragment>
該屬性用來(lái)定義需要在 fragment 內(nèi)進(jìn)行繪制的布局 layout ,從而在布局預(yù)覽界面預(yù)覽 fragment 的顯示視圖秉剑。
例如:
<fragment android:name="com.example.master.ItemListFragment"
tools:layout="@layout/list_content" />
tools:listitem / tools:listheader / tools:listfooter
適用于 <AdapterView>
還有 <ListView>
的子類(lèi)
我們知道泛豪,在編寫(xiě)列表的時(shí)候,列表的 item 布局都是在 adapter 的 getView 里通過(guò)代碼來(lái)進(jìn)行設(shè)置的,在非運(yùn)行時(shí)的環(huán)境下诡曙,無(wú)法看到列表的直接預(yù)覽效果臀叙。
這幾個(gè)屬性便提供了這樣的功能,通過(guò)直接設(shè)置對(duì)應(yīng)的 layout 布局价卤,我們可以在開(kāi)發(fā)工具的布局預(yù)覽界面直接看到顯示效果:
<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" />
tools:showIn
適用于被 <include>
標(biāo)簽引用的布局根 <view>
假設(shè) TextView 在 activity_main 布局中被 <include> 引用了劝萤,此時(shí)如果通過(guò) tools:showIn 指向 activity_main, 則此時(shí)在布局預(yù)覽界面能看到 TextView 在 activity_main 中的顯示效果。
<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" />
tools:menu
適用于部分根 <view>
這個(gè)屬性用來(lái)指定需要在 app bar 中顯示的 menu 布局慎璧,可以使用逗號(hào)分隔符來(lái)指定多個(gè) menu 布局床嫌。
<?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" />
不過(guò)目前在 toolbar 下測(cè)試并未有效,如果有小伙伴知道該屬性具體如何使用的胸私,歡迎在評(píng)論中留言哈厌处。
資源篩減屬性(Resource shrinking attributes)
該類(lèi)型屬性允許你啟用嚴(yán)格關(guān)聯(lián)檢測(cè)
并且決定在項(xiàng)目構(gòu)建的時(shí)候是否保留或丟棄指定的資源文件。
使用該屬性需要在 build.gradle 中設(shè)置 shinkResources 為 true 來(lái)開(kāi)啟資源壓縮功能岁疼。
開(kāi)啟資源壓縮后阔涉,在代碼中或資源文件中未被引用的資源會(huì)在構(gòu)建過(guò)程中被移除。
android {
...
buildTypes {
release {
shrinkResources true
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-rules.pro'
}
}
}
tools:shrinkMode
適用于 <resources>
資源標(biāo)簽
該屬性允許你指定構(gòu)建工具是否使用 "safe mode" 安全模式 (該模式會(huì)保留所有明確引用的資源以及可能被 [Resources.getIdentifier()
](https://developer.android.google.cn/reference/android/content/res/Resources.html#getIdentifier(java.lang.String, java.lang.String, java.lang.String))動(dòng)態(tài)引用的資源)
或是 "strict mode" 嚴(yán)格模式 (該模式只保留在代碼或者資源文件中明確引用的資源)
默認(rèn)情況下 shrinkMode="safe"捷绒,如果需要使用嚴(yán)格模式瑰排,則在 <resources> 中設(shè)置 tools:shrinkMode="strict"
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
tools:shrinkMode="strict" />
tools:keep
適用于 <resources>
資源標(biāo)簽
當(dāng)開(kāi)啟了資源壓縮(shrinking resource)功能時(shí),這個(gè)屬性允許你指定哪些資源需要被保留暖侨。
因?yàn)殚_(kāi)啟了資源壓縮功能后椭住,未被引用的資源文件會(huì)在構(gòu)建過(guò)程中被移除,而部分使用 [Resources.getIdentifier()
](https://developer.android.google.cn/reference/android/content/res/Resources.html#getIdentifier(java.lang.String, java.lang.String, java.lang.String)) 進(jìn)行引用的資源文件可能被誤刪它碎。
此時(shí)我們可以使用該屬性指定哪些資源需要保留函荣,不能被移除:
<?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>
資源標(biāo)簽
當(dāng)使用資源壓縮功能移除沒(méi)用的資源文件時(shí),有些資源雖然被引用了扳肛,但移除對(duì) app 不會(huì)產(chǎn)生任何影響傻挂,或者因?yàn)?Gradle plugin 錯(cuò)誤地移除了關(guān)聯(lián)的資源。
此時(shí)挖息,我們可以通過(guò)這個(gè)屬性來(lái)指定需要移除的資源:
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
tools:discard="@layout/unused_1" />