CHA1-Structure——5.理解App"資源"的內(nèi)涵

原文:Understanding App Resources

—Understanding Strings and Resources


概述


在Android中这刷,幾乎一切事物都是資源搏熄。定義在應(yīng)用程序中可訪問的資源,是Android開發(fā)的一個重要部分。

資源用于定義顏色升薯、圖像尤勋、布局、菜單和字符串值懈叹。這樣做的意義是可以使不良的“硬編碼”習(xí)慣消失。所有內(nèi)容分別定義在這些資源文件中分扎,可以被應(yīng)用程序中的代碼引用澄成。這些資源最簡單和最常見的用法是使用字符串資源,實現(xiàn)靈活的本地化文本畏吓。

資源類型

以下是Android應(yīng)用中最常用的資源類型:

Name Folder Description
Property Animations(屬性動畫) animator 定義屬性動畫的XML文件
Tween Animations(補(bǔ)間動畫) anim 定義補(bǔ)間動畫的XML文件
Drawables drawable 位圖文件或作為圖像的XML文件
Layout layout 定義用戶接口布局的XML文件
Menu menu 定義菜單或動作欄的XML文件
Values values 使用string,integer或color的XML文件

另外墨状,注意以下定義在values文件夾下的關(guān)鍵文件:

Name File Description
Colors res/values/colors.xml 顏色定義,例如文本顏色
Dimensions res/values/dimens.xml 尺寸值,例如內(nèi)邊距
Strings res/values/strings.xml 字符串值,例如文本標(biāo)題
Styles res/values/styles.xml 樣式值,例如AppBar的顏色

想了解資源類型的完整列表,請參考Providing a Resource指南菲饼。

為應(yīng)用提供資源


定義字符串資源

對于你要在應(yīng)用中展示的每一段文本(例如按鈕的標(biāo)簽或TextView上的文字)肾砂,你應(yīng)該先將文本定義在res/values/strings.xml文件中。每個條目包含一個“鍵”(代表文本的標(biāo)識)和一個“值”(文本本身)宏悦。例如镐确,如果你想在按鈕上展示“Submit”包吝,你應(yīng)該想如下的字符串資源添加到res/values/strings.xml文件中:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hello">Hello!</string>
    <string name="submit_label">Submit</string>
</resources>

現(xiàn)在我如果引用了submit_label字符串資源,默認(rèn)地將會顯示“Submit”源葫。稍后诗越,你可以創(chuàng)建全匹配的資源文件,以針對不同的系統(tǒng)語言或設(shè)備更改此值。我們還可以使用CDATA來轉(zhuǎn)義字符串息堂,以存儲更復(fù)雜的字符串(帶有html標(biāo)簽或特殊字符)嚷狞,例如:

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <string name="feedback_label">
  <![CDATA[
    Please <a >let us know</a> if you have feedback on this or if 
    you would like to log in with another identity service. Thanks! This is a longer string!  
  ]]>
  </string>
</resources>

對于字符串資源定義的更多細(xì)節(jié),請參考本篇指南荣堰。你還可以參考指南中的樣式資源其他資源類型感耙。

在應(yīng)用中引用資源

既然我們已經(jīng)定義好了自己的字符串資源,我們就能夠在Java代碼或者XML布局文件中訪問這些資源持隧。要在XML布局文件中訪問資源即硼,要使用@語法:

<Button
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@string/submit_label" />

要在Java代碼中直接訪問資源,需要使用getResources.getStringgetString 方法屡拨,訪問給定資源ID的值:

String submitText = getResources().getString(R.string.submit_label)

字符串值將會被檢索只酥。其他資源類型也采用了類似的工作機(jī)制,比如Drawable和Color等呀狼。getResourses()方法返回一個包含許多資源提取方法的Resources對象裂允。每一種資源定義在res目錄下的不同文件夾和文件中,這由它們的具體類型所決定哥艇。

定義顏色資源

除了上邊展示的字符串資源绝编,還有以下常見的資源類型。首先貌踏,讓我們看一下用于定義整個應(yīng)用中所有顏色的顏色資源文件十饥。顏色資源在res/values/colors.xml中定義,XML文件的樣式如下所示:

<?xml version="1.0" encoding="utf-8"?>
<resources>
   <color name="white">#FFFFFF</color>
   <color name="yellow">#FFFF00</color>
   <color name="fuchsia">#FF00FF</color>
</resources>

顏色資源可以在Java代碼中訪問:

// getResources().getColor():該方法目前被廢棄
// Resources res = getResources();
// int color = res.getColor(R.color.yellow); 

// 使用ContextCompatResources
int color = ContextCompat.getColor(context, R.color.yellow);

值得注意的是祖乳,當(dāng)前最新的訪問顏色資源的方式(自從API 24開始)逗堵,要求提供context來解析自定義的Theme屬性。參閱這篇文章了解更多的相關(guān)內(nèi)容眷昆。

并且在XML布局中的任意View引用顏色資源如下所示:

<TextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:textColor="@color/fuchsia"
    android:text="Hello"/>

&esmp;這是關(guān)于顏色資源你所要知道的全部內(nèi)容蜒秤,一定不要在布局文件中使用“硬編碼”的顏色值。

定義尺寸資源

接下來亚斋,我們來看一下用于定義整個應(yīng)用中所有尺寸大小的尺寸資源文件作媚。一個尺寸由一個數(shù)字后邊跟測量單位來指定。例如10px帅刊,5sp纸泡。尺寸資源在res/values/dimens.xml文件中定義,XML文件中的樣式如下所示:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="textview_height">25dp</dimen>
    <dimen name="textview_width">150dp</dimen>
    <dimen name="ball_radius">30dp</dimen>
    <dimen name="font_size">16sp</dimen>
</resources>

尺寸資源可以在Java代碼中訪問:

Resources res = getResources();
float fontSize = res.getDimension(R.dimen.font_size);

并且在XML布局中的任意View引用尺寸資源如下所示:

<TextView
    android:layout_height="@dimen/textview_height"
    android:layout_width="@dimen/textview_width"
    android:textSize="@dimen/font_size"/>

這是關(guān)于尺寸資源你所要了解的全部內(nèi)容厚掷。一定要以這種方式定義字體大小弟灼、內(nèi)間距和外邊距值,避免“硬編碼”方式出現(xiàn)冒黑。這是有關(guān)的其他資源類型田绑。

動態(tài)資源檢索

在某些情況下,你可能想通過鍵名稱而非“硬編碼”的資源ID來動態(tài)檢索資源抡爹。例如掩驱,假設(shè)我想通過單獨的鍵名稱來檢索“submit_label”字符串,就可以通過Activity中的getIdentifier方法實現(xiàn):

public String getStringValue(String key) {
    //檢索資源ID
    String packageName = getBaseContext().getPackageName();
    Resources resources = getBaseContext().getResources();
    int stringId = resources.getIdentifier(key, "string", packageName);
    if (stringId == 0) { return null; }
    //基于資源ID返回字符串值
    return resources.getString(stringId);
}

現(xiàn)在你就可以動態(tài)的引用字符串資源了:

public String myKey = "submit_label"; // 映射到R.string.submit_label
public String myStringValue = getStringValue(myKey); // Returns string text

類似的方法也能被用在其他類型的資源上冬竟。例如欧穴,通過字符串類型的ID動態(tài)檢索View:

// getViewById("tvTest");
public View getViewById(String id) {
    //檢索資源ID
    String packageName = getBaseContext().getPackageName();
    Resources resources = getBaseContext().getResources();
    int viewId = resources.getIdentifier(id, "id", packageName);
    if (viewId == 0) { return null; }
    return findViewById(viewId);
}

查看getResources對象和<a href="http://developer.android.com/reference/android/content/res/Resources.html#getIdentifier(java.lang.String, java.lang.String, java.lang.String)">getIdentifier</a>獲取更多詳細(xì)信息。

提供可替代的資源


響應(yīng)式設(shè)計

為了實現(xiàn)出色的UI設(shè)計泵殴,對于Android開發(fā)者來說涮帘,創(chuàng)建可在多種類型的備上正常工作的應(yīng)用是非常重要的。為實現(xiàn)這個目的笑诅,我們首先要根據(jù)屏幕尺寸將Android設(shè)備分為以下不同的種類:

應(yīng)用必須設(shè)計成可在多種不同的屏幕密度和屏幕尺寸上正常運行调缨。這可借助于Android框架提供的各種系統(tǒng)實現(xiàn)。

介紹可替代資源

開發(fā)者能夠使用的強(qiáng)大開發(fā)工具之一是吆你,可根據(jù)特定的限定符如手機(jī)尺寸弦叶,系統(tǒng)語言,屏幕密度等提供“替代資源”妇多。替代資源的常見用途包括:

  • 用于不同外形設(shè)備的替代布局文件(如手機(jī)VS平板)
  • 用于不同系統(tǒng)語言的替代字符串資源(如英語VS意大利語)
  • 用于不同屏幕密度的替代圖像資源
  • 用于不同平臺版本的替代樣式資源(Holo VS Material)
  • 用于不同屏幕方向的替代布局文件(portrait VS landscape)

要為一組資源指定基于特定配置下的替代資源伤哺,我們在res中以[資源類型]-[限定符]的形式創(chuàng)建一個新的目錄。一個最佳的實踐是確保為多種密度的屏幕提供了所有可適配的圖像者祖。

多種屏幕密度
多種屏幕密度

這是通過包含具有相同圖像不同版本的res/drawable-hdpi, res/drawable-xhdpi, and res/drawable-xxhdpi文件夾實現(xiàn)的立莉。正確的資源會根據(jù)設(shè)備的屏幕密度被系統(tǒng)自動選中。目錄的列表展開可能會如下所示:

res/
    drawable/   
        icon.png
        background.png    
    drawable-hdpi/  
        icon.png
        background.png

注意所有不同文件夾下的資源文件都要有相同的名字七问。該系統(tǒng)適用于具有限定符的任意類型的資源桃序。

理解限定符

Android支持多種限定符的配置,并且可以使用短線分隔限定符的方式烂瘫,將多個限定符添加到一個目錄名稱媒熊。常用的限定符如下所示:

Configuration Examples Description
Language en, fr 設(shè)備上選中的語言代碼
Screen size sw480dp,sw600dp 屏幕高度或者寬度的最小寬度
Screen orientation port, land 屏幕是出于橫屏或豎屏模式
Screen density hdpi, xhdpi 常用于可替代的圖片
Platform version v7, v11, v21 常用于樣式

你可以為單獨的一組資源,使用短線分隔方式指定多個限定符坟比。例如芦鳍,drawable-en-sw600dp-land用于英文系統(tǒng)的橫屏模式下的平板設(shè)備。注意如果你對一個資源目錄使用了多個限定符葛账,在將它們添加到目錄名中時一定要按照上表中所列出的順序柠衅。參閱完整限定符集的官方文檔。

創(chuàng)建可替代資源

在Android Studio中籍琳,創(chuàng)建可替代資源最簡單的方式是在Android項目邊欄中的資源子目錄上右擊(例如layout)菲宴,使用New => Layout resource file方法指定你期望的限定符(例如orientation):

這將會創(chuàng)建兩個版本的布局文件贷祈,一個用于豎屏模型,一個用于橫屏模式喝峦。如果你為第二個版本的布局文件添加了不同的標(biāo)簽势誊,在屏幕方向旋轉(zhuǎn)時你將發(fā)現(xiàn)這個效果會自動觸發(fā)

總結(jié)一下,你可以創(chuàng)建適用于不同情景下的多個資源文件版本谣蠢,最合適的版本會被系統(tǒng)自動選中使用粟耻。

在運行時確定配置

當(dāng)應(yīng)用正在運行時,我們可以通過Activity或Context對象的getResources().getConfiguration()方法訪問Configuration對象來檢測當(dāng)前的配置(方向眉踱,屏幕尺寸等)挤忙。例如,想要確定Activity中的屏幕方向(橫屏或豎屏)谈喳,我們通過以下方式實現(xiàn):

String image;
int orientation = getResources().getConfiguration().orientation;
if (orientation == Configuration.ORIENTATION_PORTRAIT) {
   image = "image_portrait.png";
   // ...
} else if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
   image = "image_landscape.png";
   // ...
}

類似地我們可通過訪問一個Context對象在任何對象中訪問它册烈。例如,在ArrayAdapter中使用getContext().getResources().getConfiguration()方法獲取配置婿禽。

備用布局文件

通常茄厘,替代資源用于為手機(jī)和平板指定不同的布局文件。這可以通過使用“最小寬度”限定符sw實現(xiàn)谈宛。文件夾結(jié)構(gòu)可能設(shè)置如下:

res/
    layout/   
        activity_main.xml
        item_photo.xml    
    layout-sw600dp/ 
        activity_main.xml
    layout-sw600dp-land/
        activity_main.xml 
    layout-sw720dp/ 
        activity_main.xml
        item_photo.xml
    layout-land/
        activity_main.xml
        item_photo.xml

一般來說次哈,手機(jī)和平板在sw240sw480之間。7英寸平板為sw600吆录,10英寸平板為sw720窑滞。你也可以簡單地添加限定符如layout-land,以橫屏模式應(yīng)用于所有設(shè)備恢筝。這是針對上述說明的一個例子:

有關(guān)如何管理平板設(shè)備的響應(yīng)式布局的指南哀卫,請參閱靈活的用戶接口指南。你也可以參閱這篇文章UI設(shè)計最佳實踐有關(guān)資源的官方文檔 獲取更多細(xì)節(jié)信息撬槽。

最佳布局實踐

這有一個快速檢查清單此改,可確保你的應(yīng)用可以在不同的屏幕上正常展示:

  • 避免在應(yīng)用代碼中使用硬編碼的像素值
  • 合理使用RelativeLayout,絕不使用AbsoluteLayout
  • 指定尺寸值時侄柔,使用wrap_content, match_parent, 或 dp 單位
  • 為確保響應(yīng)式的設(shè)計共啃,使用替代布局和圖像資源

在官方指南上查看屏幕獨立性的其他最佳實踐

資源別名

當(dāng)你想在多個設(shè)備配置中使用同一個資源時暂题,你不必將同一個資源文件在替代資源文件夾中拷貝多份移剪。相反,你可以創(chuàng)建替代資源薪者,作為保存在默認(rèn)資源目錄中的資源別名纵苛。

最佳資源匹配

當(dāng)你請求替代資源時,Android會基于當(dāng)前設(shè)備的配置在運行時選擇替代資源。參閱 官方資源指南了解匹配資源如何被選中的詳細(xì)概述攻人。

參考引用


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末取试,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子怀吻,更是在濱河造成了極大的恐慌瞬浓,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,366評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件烙博,死亡現(xiàn)場離奇詭異,居然都是意外死亡烟逊,警方通過查閱死者的電腦和手機(jī)渣窜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來宪躯,“玉大人乔宿,你說我怎么就攤上這事》醚” “怎么了详瑞?”我有些...
    開封第一講書人閱讀 165,689評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長臣缀。 經(jīng)常有香客問我坝橡,道長,這世上最難降的妖魔是什么精置? 我笑而不...
    開封第一講書人閱讀 58,925評論 1 295
  • 正文 為了忘掉前任计寇,我火速辦了婚禮,結(jié)果婚禮上脂倦,老公的妹妹穿的比我還像新娘番宁。我一直安慰自己,他們只是感情好赖阻,可當(dāng)我...
    茶點故事閱讀 67,942評論 6 392
  • 文/花漫 我一把揭開白布蝶押。 她就那樣靜靜地躺著,像睡著了一般火欧。 火紅的嫁衣襯著肌膚如雪棋电。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,727評論 1 305
  • 那天苇侵,我揣著相機(jī)與錄音离陶,去河邊找鬼。 笑死衅檀,一個胖子當(dāng)著我的面吹牛招刨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播哀军,決...
    沈念sama閱讀 40,447評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼沉眶,長吁一口氣:“原來是場噩夢啊……” “哼打却!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起谎倔,我...
    開封第一講書人閱讀 39,349評論 0 276
  • 序言:老撾萬榮一對情侶失蹤柳击,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后片习,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體捌肴,經(jīng)...
    沈念sama閱讀 45,820評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,990評論 3 337
  • 正文 我和宋清朗相戀三年藕咏,在試婚紗的時候發(fā)現(xiàn)自己被綠了状知。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,127評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡孽查,死狀恐怖饥悴,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情盲再,我是刑警寧澤西设,帶...
    沈念sama閱讀 35,812評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站答朋,受9級特大地震影響贷揽,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜梦碗,卻給世界環(huán)境...
    茶點故事閱讀 41,471評論 3 331
  • 文/蒙蒙 一擒滑、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧叉弦,春花似錦丐一、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至樱拴,卻和暖如春柠衍,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背晶乔。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評論 1 272
  • 我被黑心中介騙來泰國打工珍坊, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人正罢。 一個月前我還...
    沈念sama閱讀 48,388評論 3 373
  • 正文 我出身青樓阵漏,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子履怯,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,066評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,183評論 25 707
  • ¥開啟¥ 【iAPP實現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個線程回还,因...
    小菜c閱讀 6,426評論 0 17
  • 上周聽了選修課以后,我有很大的感觸叹洲。我意識到當(dāng)今世界的發(fā)展是迅速的柠硕,時代進(jìn)步是飛快的。近期出現(xiàn)了許多時代進(jìn)步的產(chǎn)物...
    這個時候微笑就好閱讀 169評論 0 0
  • 半小時后运提,我再次被帶到徐政面前蝗柔,不,不光是我民泵,是我們癣丧。清泉,孔靈翔洪灯,還有石頭坎缭。 徐政的表情很難看竟痰。 “你們幾個都是...
    咖啡苦酒閱讀 225評論 0 0
  • 啟動的兩種方式 冷啟動 當(dāng)直接從桌面上直接啟動签钩,同時后臺沒有該進(jìn)程的緩存,這個時候系統(tǒng)就需要重新創(chuàng)建一個新的進(jìn)程并...
    慕涵盛華閱讀 859評論 0 4