資源的定義
在開(kāi)發(fā)應(yīng)用的過(guò)程中初嘹,不可避免的會(huì)遇到圖像及汉,字符串等等各種類(lèi)型的引用,這些統(tǒng)稱(chēng)為資源(resource)屯烦。為了便于管理維護(hù)資源坷随,應(yīng)該在外部提供資源,而不是在代碼中直接定義資源驻龟,這個(gè)過(guò)程叫資源外部化温眉。Android中針對(duì)資源專(zhuān)門(mén)創(chuàng)建了對(duì)應(yīng)的資源目錄,在運(yùn)行的時(shí)候翁狐,系統(tǒng)會(huì)根據(jù)當(dāng)前配置使用正確的資源类溢。比如尋找屏幕適配的圖片,語(yǔ)言對(duì)應(yīng)的字符串等等谴蔑。
在資源外部化之后豌骏,系統(tǒng)會(huì)自動(dòng)分配一個(gè)資源ID,便于我們方便的訪問(wèn)資源隐锭,可以在R文件中查看資源的ID窃躲。下面是一個(gè)常規(guī)的工程目錄,res目錄下包含四個(gè)資源分類(lèi):
MyProject/
src/
MyActivity.java
res/
drawable/
graphic.png
layout/
main.xml
info.xml
mipmap/
icon.png
values/
strings.xml
不管在什么情況下,都不應(yīng)該直接將資源放在res目錄下钦睡,會(huì)導(dǎo)致編譯錯(cuò)誤蒂窒。
資源目錄分類(lèi)
外部資源支持的分類(lèi)如下表(從官網(wǎng)搬運(yùn)):
目錄 | 資源類(lèi)型 |
---|---|
animator/ |
用于定義屬性動(dòng)畫(huà)的 XML 文件。 |
anim/ |
定義漸變動(dòng)畫(huà)的 XML 文件。(屬性動(dòng)畫(huà)也可以保存在此目錄中洒琢,但是為了區(qū)分這兩種類(lèi)型秧秉,屬性動(dòng)畫(huà)首選 animator/ 目錄。) |
color/ |
用于定義顏色狀態(tài)列表的 XML 文件衰抑。請(qǐng)參閱顏色狀態(tài)列表資源 |
drawable/ |
位圖文件(.png象迎、.9.png、.jpg呛踊、.gif)或編譯為以下可繪制對(duì)象資源子類(lèi)型的 XML 文件: 位圖文件砾淌, 九宮格(.9.png,可調(diào)整大小的位圖)谭网, 狀態(tài)列表形狀動(dòng)畫(huà)汪厨,可繪制對(duì)象,其他可繪制對(duì)象 |
mipmap/ |
適用于不同啟動(dòng)器圖標(biāo)密度的可繪制對(duì)象文件 |
layout/ |
用于定義用戶界面布局的 XML 文件愉择。 請(qǐng)參閱布局資源劫乱。。 |
menu/ |
用于定義應(yīng)用菜單(如選項(xiàng)菜單锥涕、上下文菜單或子菜單)的 XML 文件衷戈。請(qǐng)參閱菜單資源。 |
raw/ |
要以原始形式保存的任意文件站楚。 要使用原始 InputStream 打開(kāi)這些資源脱惰,請(qǐng)使用資源 ID(即 R.raw.filename)調(diào)用 Resources.openRawResource() 。但是窿春,如需訪問(wèn)原始文件名和文件層次結(jié)構(gòu)拉一,則可以考慮將某些資源保存在 assets/ 目錄下(而不是 res/raw/ )。assets/ 中的文件沒(méi)有資源 ID旧乞,因此您只能使用 AssetManager 讀取這些文件蔚润。 |
values/ |
包含字符串、整型數(shù)和顏色等簡(jiǎn)單值的 XML 文件尺栖。 |
xml/ |
可以在運(yùn)行時(shí)通過(guò)調(diào)用 Resources.getXML() 讀取的任意 XML 文件嫡纠。各種 XML 配置文件(如可搜索配置)都必須保存在此處。 |
values/
目錄中的文件可描述多個(gè)資源延赌。對(duì)于此目錄中的文件除盏,<resources>
元素的每個(gè)子元素均定義一個(gè)資源。例如挫以,<string> 元素創(chuàng)建 R.string 資源者蠕,<color> 元素創(chuàng)建 R.color 資源。
每個(gè)資源均用其自己的 XML 元素定義掐松,可以根據(jù)自己的需要命名文件踱侣,并將不同的資源類(lèi)型放在一個(gè)文件中粪小。但是,為了清晰起見(jiàn)抡句,建議將不同的資源類(lèi)型放在不同的文件中探膊。 例如,對(duì)于可在此目錄中創(chuàng)建的資源待榔,下面給出了相應(yīng)的文件名約定:
arrays.xml
逞壁,用于資源數(shù)組(類(lèi)型化數(shù)組)。
colors.xml
:顏色值究抓。
dimens.xml
:尺寸值猾担。
strings.xml
:字符串值。
styles.xml
:樣式刺下。
請(qǐng)參閱字符串資源、樣式資源和更多資源類(lèi)型稽荧。
資源匹配
為了能夠正確的尋找到合適的資源橘茉,Android系統(tǒng)提供了限定符功能,程序運(yùn)行的時(shí)候姨丈,系統(tǒng)會(huì)根據(jù)當(dāng)前的設(shè)置尋找對(duì)應(yīng)的限定資源畅卓。正確使用限定符的步驟如下:
在
res/
中創(chuàng)建一個(gè)以<resources_name>-<config_qualifier>
形式命名的新目錄。
<resources_name>
是相應(yīng)默認(rèn)資源的目錄名稱(chēng)(如表 1 中所定義)蟋恬。
<qualifier>
是指定要使用這些資源的各個(gè)配置的名稱(chēng)(如表 2 中所定義)翁潘。
可以追加多個(gè) <qualifier>。以短劃線將其分隔歼争。
注意:追加多個(gè)限定符時(shí)拜马,必須按照這個(gè)表格 中列出的相同順序放置它們。如果限定符的順序錯(cuò)誤沐绒,則該資源將被忽略俩莽。將相應(yīng)的備用資源保存在此新目錄下。這些資源文件的名稱(chēng)必須與默認(rèn)資源文件完全一樣乔遮。
例如扮超,以下是一些默認(rèn)資源和備用資源:
drawable/ ---->默認(rèn)資源
icon.png
background.png
drawable-hdpi/ ---->備用資源,限定符hdpi
icon.png
background.png
關(guān)于資源的匹配規(guī)則蹋肮,官網(wǎng)已經(jīng)講解的非常詳細(xì)了出刷,這里只介紹一些常用的內(nèi)容。
- Drawable的限定符
drawable文件夾后面的限定符常見(jiàn)的有l(wèi)dpi坯辩,mdpi馁龟,hdpi,xhdpi濒翻,xxhdpi屁柏,xxxhpdi啦膜。他們所代表的都是屏幕的密度。除此之外淌喻,還有nodpi僧家,tvdpi,anydpi裸删,他們的區(qū)別如下:
限定符 | 含義 |
---|---|
ldpi: | 低密度屏幕八拱;約為 120dpi。 |
mdpi: | 中等密度(傳統(tǒng) HVGA)屏幕涯塔;約為 160dpi肌稻。 |
hdpi: | 高密度屏幕;約為 240dpi匕荸。 |
xhdpi: | 超高密度屏幕爹谭;約為 320dpi。此項(xiàng)為 API 級(jí)別 8 中新增配置 |
xxhdpi: | 超超高密度屏幕榛搔;約為 480dpi诺凡。此項(xiàng)為 API 級(jí)別 16 中新增配置 |
xxxhdpi: | 超超超高密度屏幕使用(僅限啟動(dòng)器圖標(biāo));約為 640dpi践惑。 此項(xiàng)為 API 級(jí)別 18 中新增配置 |
nodpi: | 它可用于您不希望縮放以匹配設(shè)備密度的位圖資源腹泌。 |
tvdpi: | 密度介于 mdpi 和 hdpi 之間的屏幕;約為 213dpi尔觉。它并不是“主要”密度組凉袱, 主要用于電視,而大多數(shù)應(yīng)用都不需要它侦铜。對(duì)于大多數(shù)應(yīng)用而言专甩,提供 mdpi 和 hdpi 資源便已足夠,系統(tǒng)將根據(jù)需要對(duì)其進(jìn)行縮放泵额。此項(xiàng)為 API 級(jí)別 13 中新增配置 |
anydpi: | 此限定符適合所有屏幕密度配深,其優(yōu)先級(jí)高于其他限定符。 這對(duì)于矢量可繪制對(duì)象很有用嫁盲。 此項(xiàng)為 API 級(jí)別 21 中新增配置 |
通常情況下篓叶,我們將各種尺寸對(duì)應(yīng)的圖片放到各自文件夾下就可以了,如果系統(tǒng)找不到對(duì)應(yīng)的資源羞秤,會(huì)去尋找相近的最適合的資源缸托,這時(shí)候,顯示出來(lái)的效果就會(huì)有差異了:
這6個(gè)主要密度的比例為 3:4:6:8:12:16瘾蛋,假設(shè)當(dāng)前屏幕密度為240dpi俐镐,對(duì)應(yīng)的資源為hdpi,我們有一張圖片尺寸為100*100px哺哼,把它放在hdpi目錄下佩抹,顯示的效果是沒(méi)有問(wèn)題的叼风,仍然是100*100px。如果hdpi下面沒(méi)有會(huì)怎么樣棍苹?
系統(tǒng)會(huì)尋找最相近的合適的資源无宿。在hdpi下找不到,會(huì)去更高密度的xhdpi尋找枢里,還是找不到就繼續(xù)向上孽鸡,一直到最高的xxhdpi,都沒(méi)有找到的話栏豺,再去nodpi尋找彬碱,仍然沒(méi)有的話就只能向下尋找了,到mdp-->ldpi奥洼。
再回到上邊的例子巷疼,如果我們把圖片放到xhdpi目錄下,系統(tǒng)找到圖片之后灵奖,并不會(huì)直接引用皮迟。它會(huì)認(rèn)為該圖片是為xhdpi準(zhǔn)備的,為了適應(yīng)當(dāng)前的hdpi桑寨,會(huì)對(duì)圖片進(jìn)行縮放,在這里就是縮小了忿檩,縮小比例就是hdpi:xhdpi = 6:8尉尾,最終顯示出來(lái)的圖片大小也不再是100*100px,而是100(6/8)=75*75px
所以燥透,如果我們想在高密度的屏幕上顯示圖片沙咏,應(yīng)該為他制定對(duì)應(yīng)的資源,否則系統(tǒng)會(huì)去低密度目錄下尋找資源班套,然后對(duì)它放大肢藐,會(huì)占用極高的內(nèi)存。
nodpi目錄下的圖片不會(huì)被縮放吱韭,在任何屏幕上都是它本身的尺寸吆豹,只有在更高密度的目錄下沒(méi)有找到資源時(shí)才會(huì)到這里尋找。
-
mipmap
mipmap是android Studio里為應(yīng)用啟動(dòng)圖標(biāo)專(zhuān)門(mén)設(shè)置的文件夾理盆。建議的啟動(dòng)圖標(biāo)尺寸對(duì)應(yīng)如下:
密度 | 建議尺寸 |
---|---|
mipmap-mdpi | 48 * 48 |
mipmap-hdpi | 72 * 72 |
mipmap-xhdpi | 96 * 96 |
mipmap-xxhdpi | 144 * 144 |
mipmap-xxxhdpi | 192 * 192 |
Values資源
上面已經(jīng)提過(guò)了痘煤,values支持多種資源,這些資源都是一些常量的定義猿规,它們統(tǒng)統(tǒng)放在values目錄下衷快。values的根標(biāo)簽為<resources>
,可包含的類(lèi)型主要有以下這些
- String, String Array, Quantity Strings姨俩,plurals
單獨(dú)用<string>標(biāo)簽可以設(shè)定單個(gè)字符串
<resources>
<string name="hello">Hello!</string>
</resources>
----------------------------
textview中調(diào)用
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello" />
--------------------
在代碼中使用:
String string = getString(R.string.hello);
字符串也可以使用占位符蘸拔,%1表示位置結(jié)束宝冕。
<string name="msg">hello, %1$s, you have %2$d messages!</string>
----------------------
引用:
getString(R.string.msg,"jim",5);
可以接收的類(lèi)型:%s(字符串),c(字符)陨晶,b(布爾型)猬仁,d(十進(jìn)制整型),o(8進(jìn)制整型)先誉,x(16進(jìn)制整型)湿刽,n(換行),f(浮點(diǎn)型)褐耳,%(百分比)
定義字符串的時(shí)候诈闺,是不需要用 雙引號(hào) "" 來(lái)包裹的,如果字符串本身包含了單引號(hào) ' 或者雙引號(hào) " 铃芦,必須進(jìn)行轉(zhuǎn)義處理雅镊,前邊加一個(gè)反斜杠 \ 。只包含單引號(hào)的話刃滓,可以用雙引號(hào)將整個(gè)字符串包裹起來(lái)仁烹。如果不進(jìn)行處理,引號(hào)顯示不出來(lái)咧虎。
<string name="good_example">This\'ll work</string>
<string name="good_example_2">"This'll also work"</string >
<string name="bad_example">This doesn't work</string>
--------------------------
<string name="good_example">This is a \"good string\".</string>
<string name="bad_example">This is a "bad string".</string>
<!-- Quotes are stripped; displays as: This is a bad string. -->
復(fù)數(shù)plurals可以指定根據(jù)輸入內(nèi)容(0,1,2等等)卓缰,選擇對(duì)應(yīng)的字符串。
<plurals name="person">
<item quantity="one">%d person </item>
<item quantity="other">%1$d persons </item>
</plurals>
-----------------------------------
str+=getResources().getQuantityString(R.plurals.person, 1,1);
str+="\n";
str+=getResources().getQuantityString(R.plurals.person, 2,2);
tx.setText(str);
String Array用來(lái)定義一個(gè)數(shù)組:
<resources>
<string-array name="planets_array">
<item>Mercury</item>
<item>Venus</item>
<item>Earth</item>
<item>Mars</item>
</string-array>
</resources>
--------------
Resources res = getResources();
String[] planets = res.getStringArray(R.array.planets_array);
-
Color砰诵,Dimension
Color用來(lái)定義顏色征唬,Dimension定義尺寸。定義好之后就可以在xml文件或者代碼中直接使用了茁彭。
<color name="colorPrimary">#4caf50</color>
<dimen name="material_8dp">8dip</dimen>
---------------------
<ImageView
android:background="@color/colorPrimary"
android:layout_width="@dimen/material_8dp"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher"/>
-
Integer, Integer Array总寒,fraction,Boolean
這些都是基本數(shù)據(jù)類(lèi)型理肺,使用很簡(jiǎn)單摄闸,直接看下面例子就可以了:
<integer name="max_speed">75</integer>
<integer name="min_speed">5</integer>
Resources res = getResources();
int maxSpeed = res.getInteger(R.integer.max_speed);
------------------------------
<integer-array name="bits">
<item>4</item>
<item>8</item>
<item>16</item>
<item>32</item>
</integer-array>
Resources res = getResources();
int[] bits = res.getIntArray(R.array.bits);
---------------------------
<bool name="screen_small">true</bool>
<bool name="adjust_view_bounds">true</bool>
Resources res = getResources();
boolean screenIsSmall = res.getBoolean(R.bool.screen_small);
<ImageView
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:src="@drawable/logo"
android:adjustViewBounds="@bool/adjust_view_bounds" />
Color
-
Type Array
TypeArray用來(lái)定義其他類(lèi)型資源的數(shù)組,比如drawable哲嘲,顏色等贪薪。
<array name="icons">
<item>@drawable/home</item>
<item>@drawable/settings</item>
<item>@drawable/logout</item>
</array>
<array name="colors">
<item>#FFFF0000</item>
<item>#FF00FF00</item>
<item>#FF0000FF</item>
</array>
Resources res = getResources();
TypedArray icons = res.obtainTypedArray(R.array.icons);
Drawable drawable = icons.getDrawable(0);
TypedArray colors = res.obtainTypedArray(R.array.colors);
int color = colors.getColor(0,0);
- Item
<resources>的子標(biāo)簽<item>是一個(gè)比較特殊的標(biāo)簽,它可以通過(guò)type來(lái)表示任何類(lèi)型眠副,它相當(dāng)于為已存在的資源指定一個(gè)別名画切。看下邊的例子:
<item name="luncher"type="drawable">@drawable/ic_launcher</item>
<item name="main_layout" type="layout">@layout/activity_main</item>
這里定義了兩個(gè)item囱怕,一個(gè)是drawable霍弹,另一個(gè)是layout毫别,我們使用的時(shí)候,使用R.drawable.ic_luncher
和R.drawable.luncher
典格,最終指向的都是同一個(gè)圖片岛宦。
Android里的資源類(lèi)型比較多,在備用資源不多的時(shí)候耍缴,對(duì)每一種類(lèi)型都設(shè)置限定符來(lái)專(zhuān)門(mén)分配一個(gè)目錄似乎有些麻煩砾肺,這時(shí)候可以使用item。
首先新建一個(gè)存放item的xml文件防嗡,比如refs.xml变汪,在這里定義一個(gè)item,指向默認(rèn)的資源蚁趁。然后新建帶限定符的values目錄裙盾,例如values-sw600dp,新建一個(gè)同樣的xml文件,在這個(gè)文件中定義一個(gè)同樣name的item他嫡,指向600dp所需的資源番官。在使用的使用,引用item中指定的name就可以了钢属。