利用tools命名空間嫂沉,android studio支持很多XML屬性,當(dāng)構(gòu)建app時這些屬性會被擦除扮碧,對APK的大小和運行時行為沒有任何影響输瓜。請看官網(wǎng)。
tools屬性大致可以分為三類:1芬萍,錯誤處理屬性尤揣,這樣就會影響到Lint的提示;2柬祠,資源shrink屬性北戏,影響到資源以何種方式shrink;3漫蛔,布局編輯器設(shè)計時View屬性嗜愈。
1 錯誤處理屬性
- tools:ignore
任何元素都可以使用這個屬性,比如strings.xml里面的string元素莽龟,我們可以忽略掉MissingTranslation這個錯誤屬性:
<string name="show_all_apps" tools:ignore="MissingTranslation">All</string>
再比如對于下面代碼中的ImageView元素蠕嫁,如果我們沒有添加tools:ignore這個屬性,那么Lint會提示該ImageView缺少android:contentDescription屬性毯盈,tools:ignore="contentDescription"可以忽略這個警告:
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/divider"
tools:ignore="contentDescription" />
- tools:targetApi
任何元素都可以使用這個屬性剃毒,它和java代碼中的注解@TargetApi是一樣的:它指定了當(dāng)前元素支持API級別,屬性值既可以是數(shù)字也可以是代碼名字。
這樣的話赘阀,即使指定的minSdkVersion
不支持當(dāng)前元素益缠,那么Lint也不會警告。比如設(shè)置的minSdkVersion=12
基公,但是要使用GridLayout
的話幅慌,就必須加上tools:targetApi="14"
:
<GridLayout android:layout_width="match_parent"
android:layout_height="match_parent"
tools:targetApi="ice_cream_sandwich"/>
- tools:locale
只有resources標(biāo)簽才能使用這個屬性。resources默認(rèn)的語言和區(qū)域是英語轰豆,會進行拼寫檢查胰伍,而這個屬性過指定了resources的語言和區(qū)域,當(dāng)然屬性值必須是合法的locale qualifier酸休。
比如你可以指定values/strings.xml
文件的默認(rèn)語言是西班牙語而不是英語:
<resources xmlns:tools="http://schemas.android.com/tools" tools:locale="es">
2 資源壓縮模式
當(dāng)使用resource shrinking的時候下面的屬性指定資源壓縮的一些特性骂租。
為了使用資源壓縮,請將build.gradle
文件的shrinkResources
屬性置為true
雨席,(minifyEnabled
屬性是code shrinking代碼壓縮):
android {
...
buildTypes {
release {
shrinkResources true
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
- tools:shrinkMode
適用對象:<resources>
菩咨。指定構(gòu)建的時候是使用safe mode還是strict mode。safe mode保留所有直接引用的資源和可能動態(tài)使用的資源陡厘,比如Resources.getIdentifier()方式調(diào)用的資源抽米。strict mode只保留直接引用的資源。
默認(rèn)的安全模式是shrinkMode="safe"
糙置。如果要使用strict mode云茸,可以用下面的代碼:
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
tools:shrinkMode="strict" />
如果啟用了strict mode,可以自定義要保留的資源谤饭,如果想要保留或舍棄的特定資源标捺,在您的項目中創(chuàng)建一個包含 <resources> 標(biāo)記的 XML 文件,并在 tools:keep 屬性中指定每個要保留的資源揉抵,在tools:discard屬性中指定每個要舍棄的資源亡容。這兩個屬性都接受逗號分隔的資源名稱列表。您可以使用星號字符作為通配符冤今。例如:
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
tools:keep="@layout/l_used*_c,@layout/l_used_a,@layout/l_used_b*"
tools:discard="@layout/unused2" />
將該文件保存在項目資源中闺兢,例如,保存在 res/raw/keep.xml戏罢。構(gòu)建不會將該文件打包到 APK 之中屋谭。
更多信息請查看:Shrink your resources。
- tools:keep
適用對象:<resources>
標(biāo)簽龟糕。這個屬性能夠保留特定的資源桐磁,比如Resources.getIdentifier())動態(tài)使用的資源。用法是可以創(chuàng)建res/raw/keep.xml
文件讲岁,內(nèi)容如下:
<?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)簽我擂。有些資源可能被引用但是又對app沒有影響衬以,不能直接刪除這些資源,那么這個屬性可以移除這些資源扶踊;或者Gradle插件錯誤地推斷這些資源是被引用的泄鹏,那么也可以使用這個屬性郎任。用法如下:
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
tools:discard="@layout/unused_1" />
3 布局編輯器設(shè)計時View屬性
- tools:替換android:
tools可以覆蓋所有的android屬性秧耗,相信這個是大家用過的最多的,就不說了舶治。
- tools:parentTag
android studio2.2新加了這個屬性可以指定merge標(biāo)簽的布局類型分井,比如:
<merge 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:parentTag="android.widget.LinearLayout">
</merge>
- tools:context
只有根View才能使用這個屬性,它指定了當(dāng)前布局默認(rèn)是跟哪個Activity相關(guān)聯(lián)霉猛,使得布局獲取那個Activity的一些信息比如Activity使用的theme等等尺锚,而且當(dāng)你使用quickfix(mac上的快捷鍵是alt+enter)給子View添加`onClick事件時,相應(yīng)的方法代碼會插入到這個Activity中惜浅。
- tools:itemCount
只有RecyclerView才能使用這個屬性瘫辩。我的android studio版本是3.0.1,布局編輯器中RecyclerView顯示的默認(rèn)個數(shù)是10個坛悉,這個屬性可以改變RecyclerView顯示的個數(shù)伐厌。
- tools:layout
只有fragment標(biāo)簽?zāi)苡眠@個屬性,在preview窗口中可以預(yù)覽這個layout的樣式裸影。
- tools:listitem / tools:listheader / tools:listfooter
只有AdapterView才能使用這個屬性挣轨,指定了列表的items、header和footer的布局轩猩,不過tools:listitem這個屬性RecyclerView也能使用:
<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>
引用的任何根View:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView 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:showIn="@layout/app_bar_main"
tools:itemCount="32">
</android.support.v7.widget.RecyclerView>
- tools:menu
適用對象:根<View>
卷扮。告訴IDE 在預(yù)覽窗口中使用哪個菜單,這個菜單將顯示在layout的根節(jié)點上(actionbar的位置)均践。
preview窗口很智能晤锹,如果布局和一個activity關(guān)聯(lián)(通過tools:context指定)它將會自動查詢這個activity的onCreateOptionsMenu方法,以顯示菜單彤委,而tools:menu屬性則可以覆蓋這種默認(rèn)的行為鞭铆。
屬性的值是menu id,還可以有多個葫慎,不同的menu id之間用逗號隔開衔彻。
需要注意的是,主題為Theme.AppCompat時偷办,這個屬性不起作用艰额。
- tools:actionBarNavMode
指定actionbar的顯示模式,其值可以是:1. standard椒涯、2. tabs柄沮、3. list
<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:actionBarNavMode="tabs" />
同樣的,當(dāng)主題是Theme.AppCompat (r21+, at least) 或者Theme.Material,或者使用了布局包含Toolbar的方式。 該屬性也不起作用祖搓,只有holo主題才有效狱意。參考
- tools:minValue / tools:maxValue
適用對象:NumberPicker
。預(yù)覽NumberPicker的最大最小值但是不生效拯欧。NumberPicker的maxValue和minValue只能通過代碼設(shè)置详囤,如果想通過xml設(shè)置的話需要另想辦法,這里有參考镐作。為什么android studio的xml不支持設(shè)置這兩個屬性呢藏姐?我不懂,請大神留言告知该贾。
<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>
羔杨。讓DrawerLayout打開一個方向。
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. |
<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/*" resources
適用對象:所有支持文本和圖片的View杨蛋。這個屬性相當(dāng)于給View加了個placeholder兜材,比如:
<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" />
下面的表格描述了所有能給View使用的placeholder:
Attribute value | Description of placeholder data |
---|---|
@tools:sample/full_names | Full names that are randomly generated from the combination of @tools:sample/first_names and @tools:sample/last_names. |
@tools:sample/first_names | Common first names. |
@tools:sample/last_names | Common last names. |
@tools:sample/cities | Names of cities from across the world. |
@tools:sample/us_zipcodes | Randomly generated US zipcodes. |
@tools:sample/us_phones | Randomly generated phone numbers with the following format: (800) 555-xxxx. |
@tools:sample/lorem/random | Placeholder text that is derived from Latin. |
@tools:sample/date/day_of_week | Randomized dates and times for the specified format. |
@tools:sample/date/ddmmyy | 同上 |
@tools:sample/date/mmddyy | 同上 |
@tools:sample/date/hhmm | 同上 |
@tools:sample/date/hhmmss | 同上 |
@tools:sample/avatars | Vector drawables that you can use as profile avatars. |
@tools:sample/backgrounds/scenic | Images that you can use as backgrounds. |
這些placeholder資源不會打進APK包里面,因此不用擔(dān)心會增加app體積逞力,只是方便在preview窗口查看預(yù)覽效果曙寡。
下面舉兩個例子。
- 例子1 原文鏈接
比如下面的代碼定義了一個RecyclerView掏击,它的tools:listitem="@layout/item_part1"
:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:listitem="@layout/item_part1" />
再來看下item_part1.xml的代碼:
//item_part1.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/avatar"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:contentDescription="@null"
app:layout_constraintDimensionRatio="h,1:1"
app:layout_constraintEnd_toStartOf="@id/name"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/name"
tools:src="@tools:sample/avatars"/>
<TextView
android:id="@+id/name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="8dp"
app:layout_constraintBottom_toTopOf="@+id/city"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_weight="5"
app:layout_constraintStart_toEndOf="@id/avatar"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed"
tools:text="@tools:sample/full_names"/>
<TextView
android:id="@+id/city"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
app:layout_constraintBottom_toTopOf="@id/description"
app:layout_constraintEnd_toStartOf="@id/date"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintStart_toEndOf="@id/avatar"
app:layout_constraintTop_toBottomOf="@+id/name"
tools:text="@tools:sample/cities"/>
<TextView
android:id="@+id/date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:gravity="end"
app:layout_constraintBaseline_toBaselineOf="@id/city"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/city"
tools:text="@tools:sample/date/ddmmyy"/>
<TextView
android:id="@+id/description"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:ellipsize="end"
android:maxLines="3"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/avatar"
app:layout_constraintTop_toBottomOf="@+id/city"
tools:text="@tools:sample/lorem/random"/>
</android.support.constraint.ConstraintLayout>
從上面的代碼可以看到卵皂,RecyclerView的item包含5個元素:頭像avatar、名字name砚亭、城市city灯变、日期date和描述description。頭像avatar使用的屬性是tools:src="@tools:sample/avatars"
捅膘,名字name使用的屬性是tools:text="@tools:sample/full_names"
添祸,城市city使用的屬性是tools:text="@tools:sample/cities"
,日期date使用的屬性是tools:text="@tools:sample/date/ddmmyy"
寻仗,描述description使用的屬性是tools:text="@tools:sample/lorem/random"
刃泌,最終的preview窗口如圖所示:
例子1的 代碼地址
- 例子2 原文鏈接
然后我們創(chuàng)建一個“names”文件箕别,每一行加一個名字:
//ampledata/names
Mark Allison
Sir Reginald Fortescue Crumplington-Smythe
Pablo Diego José Francisco de Paula Juan Nepomuceno María de los Remedios Cipriano de la Santísima Trinidad Ruiz y Picasso
Millicent Marbles
然后我們把原來的placeholder屬性tools:text="@tools:sample/full_names"
替換一下:
<TextView
android:id="@+id/name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="8dp"
app:layout_constraintBottom_toTopOf="@+id/city"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_weight="5"
app:layout_constraintStart_toEndOf="@id/avatar"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed"
tools:text="@sample/names" />
自定義完名字name铜幽,我們再來自定義頭像avatar滞谢。在sampledata目錄下創(chuàng)建avatars目錄:代碼使用下面的方式調(diào)用:
<ImageView
android:id="@+id/avatar"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:contentDescription="@null"
app:layout_constraintDimensionRatio="h,1:1"
app:layout_constraintEnd_toStartOf="@id/name"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/name"
tools:src="@sample/avatars" />
再來看preview窗口,我們添加了四個頭像的VectorDrawable但是preview窗口只顯示了2個:json文件內(nèi)容如下:
{
"data": [
{
"city": "Hemel Hempstead, Hertfordshire, UK",
"avatar": "@sample/avatars"
},
{
"city": "Brokenwind, Aberdeenshire, UK",
"avatar": "@sample/avatars"
},
{
"city": "Málaga, Espa?a",
"avatar": "@sample/avatars"
},
{
"city": "Batchelors Bump, Essex, UK",
"avatar": "@sample/avatars"
}
]
}
然后我們的頭像avatar和城市city就能使用這個json文件來引用:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/avatar"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:contentDescription="@null"
app:layout_constraintDimensionRatio="h,1:1"
app:layout_constraintEnd_toStartOf="@id/name"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/name"
tools:src="@sample/users.json/data/avatar"/>
<TextView
android:id="@+id/name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="8dp"
app:layout_constraintBottom_toTopOf="@+id/city"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_weight="5"
app:layout_constraintStart_toEndOf="@id/avatar"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed"
tools:text="@sample/names"/>
<TextView
android:id="@+id/city"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
app:layout_constraintBottom_toTopOf="@id/description"
app:layout_constraintEnd_toStartOf="@id/date"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintStart_toEndOf="@id/avatar"
app:layout_constraintTop_toBottomOf="@+id/name"
tools:text="@sample/users.json/data/city"/>
<TextView
android:id="@+id/date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:gravity="end"
app:layout_constraintBaseline_toBaselineOf="@id/city"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/city"
tools:text="@tools:sample/date/ddmmyy"/>
<TextView
android:id="@+id/description"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:ellipsize="end"
android:maxLines="3"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/avatar"
app:layout_constraintTop_toBottomOf="@+id/city"
tools:text="@tools:sample/lorem/random"/>
</android.support.constraint.ConstraintLayout>
最終的preview窗口:例子2的 代碼地址