瞭解Android資源(上)

在Android開發中,資源包括文件或者值,它們和執行應用捆綁,無需在源代碼中寫死,因此我們可以改變或替換他們,而無需對應用重新編譯。

Pro <wbr>Android學習筆記(三):瞭解Android資源(上)

瞭解資源構成

參考閱讀Android學習筆記(三八):資源resource(上)、XML解析(XmlPullParser)Android學習筆記(三九):資源resource(下)

Strings資源。位於res/values下,可以有一個或多個xml文件。其中最爲常見的是strings.xml,對於demo這類小例子,爲了方便常全部都放在strings.xml中,但實際開發中,應進行合理組織。下面事xml文件的例子:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">Pro Android</string>
    <string name="action_settings">Settings</string>
    <string name="resource_test">Understanding Resources</string>
</resources>

需要留意,對於標準的xml文件,有xmlns來指明schema,在此可以省略。如果非要加上,可以爲: 。每定義一個string,在R.java文件中將自動生成ID,由此可以通過ID,如R.string.app_name進行對應,ID事int,但Android或根據需要轉換爲對應的string。

public final class R {
    … …
    public static final class string {
        public static final int action_settings=0x7f050001;
        public static final int app_name=0x7f050000;
        public static final int resource_test=0x7f050002;
    }
    … …
}

Layout資源。res/layout下放着關鍵的View,每個activity或者每個screen要單獨xml來描述。在代碼用setContentView ( R.layout.xxxx ) 來進行映射。而layout xml文件中的view,則用R.id.xxxx來映射,可以通過findViewById來獲取具體view的對象。

Resource Reference Syntax資源參考語法。用於分配在Android xml文件某個資源的ID的語法稱爲資源參考語法,具體爲@[ package:] type/name,例如android:id="@+id/t1"。”+”表示如果t1的id沒有定義爲資源,去爲它定義一個唯一的Id號碼。實際上,我們可以預先定義id,以後再使用,方式如下,在res/values下的xml文件中進行定義。定義後,我們將在R.java文件中發現有關的R.id.t2的定義,如是,我們將使用android:id="@id/t2"。

<resources>
    <item type="id" name="t2"/>
</resources>

這裏的type是對應R.java裏面的資源類別的namespace,例如R.string則對應爲string。此外可以是drawable,id,layout,string,attr,plurals,string-array(在R.java中爲R.array)。這裏的name,是指資源的名稱,也對應R.java中ID名字。如果沒有package,就是使用本地資源,和本app的R.java中。Andriod同時也提供了一些組件,例如ListView,使用<ListView android:id=”@android:id/list”…… />,這使用了android.R.java文件,實時上,我們可以使用其他包名,用該包下的R.java文件來解釋。

編譯和非編譯的資源。資源來源兩類文件:XML和raw文件,對應的也可以分爲編譯爲二進制格式的,和非編譯直接copy的。對於一般的資源XML文件,需要將XML的節點翻譯的ID,所以需要編譯爲binary。其中res/xml中可放置任何XML格式的文件,如們自定的,可以通過R.xml.<file_name>來指向該資源,並用Android提供的XML reader來解析,如XMLPullPaser。

非編譯爲binary的文件位於res/raw,和所有res/下的資源一樣,可用R.raw.<file_name>來獲取該資源。讀取是需使用stream-based的API,如下。audio和video文件屬於這類raw文件,當然如果我們需要,也可以將一個xml文件放入res/raw目錄下,作爲raw文件來使用。

BufferedReader reader=new BufferedReader(new InputStreamReader(getResources().openRawResource(R.raw.w_city_code)));

主要的關鍵資源

String Arrays。位於res/values/*.xml,格式如下:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string-array name="rt_test_array">
        <item>one</item>
        <item>two</item>
        <item>three</item>
    </string-array>
</resources>

在R.java中自動生成ID,可以在用R.array.xxxx來調用

public final class R {
    public static final class array {
        public static final int rt_test_array=0x7f050000;
    }  
   … … 
}

在程序中可以如下調用

//通過getResources()獲取activity的resource對象,通過該對象獲取string-array資源
String strs[] = getResources().getStringArray(R.array.rt_test_array);
for(String s: strs){
   ……
}

複數Plurals。這對中文而言沒有什麼意義,但是在英文中,有There is one egg. 和There are 5 eggs. 的區別。需要在信息表達方面進行區分對待,plurals就是針對此進行處理。

Pro <wbr>Android學習筆記(三):瞭解Android資源(上)

在quantity中有效的選擇顯示有6個,但是如果locale爲en時,實際有效的是“one”和“other”,設置其餘的,經試驗,並無效果。書中言,對於其他的語言設置也是這樣,除了捷克語,對於2-4,對應爲few。

Resources res = getResources();  //獲取資源對象
//res.getQuantityString(),第一個參數爲plurals的ID,第二參數爲0,對應quantity的選擇,由於有效的只有1和其他,則對應other,因此s1爲There are %d eggs.
String s1= res.getQuantityString(R.plurals.rt_test_plurals, 0);
//第二個參數爲0,對應other,第三個參數爲2,是根據format對%d的填充,即爲There are 0 eggs.
s1= res.getQuantityString(R.plurals.rt_test_plurals, 0,2);
//第二個參數爲1,對應one,即爲There is 1 egg.
s1= res.getQuantityString(R.plurals.rt_test_plurals, 1);
//第二個參數爲1,對應one,由於format沒有需要填入,爲There is 1 egg.
s1= res.getQuantityString(R.plurals.rt_test_plurals, 1,1);
//第二個參數爲2,對應other,由於format有input,爲There are 6 eggs.
s1= res.getQuantityString(R.plurals.rt_test_plurals, 2,6);

Wei:經過試驗,在XML中用%s來替代%d是可行的,但是如果input的數目超過1個,如2個或以上,則在編譯時會報錯。plurals就只是爲了處理西文中複數的問題,不要搞得太複雜。對於上面的例子,第二和第三參數應該匹配,這樣才便於閱讀,例如res.getQuantityString(R.plurals.rt_test_plurals,6,6)。

再談String。string資源可以帶有輸入,可以帶有html格式。我們看看以下的string資源的獲取和輸出。

Pro <wbr>Android學習筆記(三):瞭解Android資源(上)

我們通過下面的代碼在TextView tv中進行輸入。

Pro <wbr>Android學習筆記(三):瞭解Android資源(上)

tv.append ( getString(R.string.rt_simple_string)) );
tv.append (“\n”));
...... //依次在tv中顯示string
tv.append (getString(R.string.rt_format_string,"World","my friend") );
...... //依次在tv中顯示string

//特別留意最後兩個。在資源中帶有HTML的格式,如果仍用<b></b>,在獲取資源時,這部分信息會消失,需要用 &lt; 和 &gt; 來表示左右尖括號。多少有些麻煩。此外要使HTML格式有效,需要告知TextView這是一個HTML格式,否則會直接將<b></b>作爲字符串內容顯示。下面試驗再次證明需要將尖括號改寫。

Pro <wbr>Android學習筆記(三):瞭解Android資源(上)

tv.append ( Html.fromHtmlgetString(rt_html_string1) + "<br/>") );
tv.append ( Html.fromHtmlgetString(rt_html_string2)+ "<br/>") );

我們可以在view中直接引用string,如 andriod:text=”@string/rt_simple_string”。

Color。color資源同樣在res/values/下面定義。

<color name="rt_blue">#0000f0</color>

代碼調用如下。處理我們定義,我們還可以使用Android預定義的一些顏色,具體可以參考http://developer.android.com/reference/android/R.color.html#background_light

int color = getResources().getColor(R.color.rt_blue);
tv.setTextColor(color);
tv.setBackgroundColor(getResources().getColor(android.R.color.background_dark));

Dimension。同樣,在res/values/下任何xml文件可以定義

<dimen name="rt_dp">5dp</dimen>,
其中dp爲Android的尺寸單位,Android長度單位詳解(dp、sp、px、in、pt、mm、dip) ,android中定義的dimension單位有以下這些:
px(Pixels ,像素)            :對應屏幕上的實際像素點。
in(Inches ,英寸)            :屏幕物理長度單位。
mm(Millimeters ,毫米):屏幕物理長度單位。
pt(Points ,磅)               :屏幕物理長度單位,1/72英寸。
dp(與密度無關的像素)     :邏輯長度單位,在 160 dpi 屏幕上,1dp=1px=1/160英寸。隨着密度變化,對應的像素數量也變化,但並沒有直接的變化比例。
dip                                      :與dp相同,多用於Google示例中。
sp(與密度和字體縮放度無關的像素):與dp類似,但是可以根據用戶的字體大小首選項進行縮放。

從資源中獲取dimension如下,可以在setTextSize( )等場合使用dimension,或者直接在XML中設置android:textSize="@dimen/rt_dp"

float dimen = getResources().getDimension(R.dimen.rt_dp);

Pro <wbr>Android學習筆記(三):瞭解Android資源(上)

Image資源。由於手機尺寸的不同,同一個圖片,可製造成不同的尺寸,放置在res/drawable-?dpi中,系統會進行自動選擇,ic_launcher圖標。我們也可以不考慮手機實際尺寸,使用同一個圖標,可以放置在res/drawable中。試驗,爲了簡單,採用同一尺寸。圖片的格式可以是*.gif,*.jpg和*.png。

實驗中我們將sample_image.png放置到drawble。在XML中可以如下引用

Pro <wbr>Android學習筆記(三):瞭解Android資源(上)

第一個圖中圖片出現伸拉

<Button android:id="@+id/vt_button1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@string/resource_test"

    android:background="@drawable/sample_image"/>
<ImageButton android:id="@+id/vt_img_button3"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:contentDescription="@string/resource_test"
    android:src="@drawable/sample_image"/>

當然,也可以在java編碼中來調用。如下

Drawable d = getResources().getDrawable(R.drawable.sample_image);
button.setBackground(d);
等同於下面
button.setBackgroundResource(R.drawable.ic_launcher);
絕大部分的view都具有setBackground的方法。

Wei:在Android的API Guides中這樣寫道:A bitmap graphic file (<.png, .jpg, or .gif). Creates a BitmapDrawable. 但getDrawable()返回的Drawble。同樣根據API Guides,我們可以通過設置bitmap xml來,而這個輸出BitmapDrawable,該XML放置在res/drawable/下,如下

<?xml version="1.0" encoding="utf-8"?>
<bitmap
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@[package:]drawable/drawable_resource"
    android:antialias=["true" | "false"]
    android:dither=["true" | "false"]
    android:filter=["true" | "false"]
    android:gravity=["top" | "bottom" | "left" | "right" | "center_vertical" |
                      "fill_vertical" | "center_horizontal" | "fill_horizontal" |
                      "center" | "fill" | "clip_vertical" | "clip_horizontal"]
    android:tileMode=["disabled" | "clamp" | "repeat" | "mirror"] />

Color-Drawable資源。在了image外,drawable資源還可以是color-drawable,也就是一個顏色方框。定義顏色方框,可以在res/values中任何XML文件中加入:

<resource>
    <drawable name="red_rectangle">#f00</drawable>
    <drawable name="blue_rectangle">#0000ff</drawable>
    <drawable name="green_rectangle">#00f0f0</drawable>
</resource>

在view的xml中,同樣可以設置

android:background="@drawable/red_rectangle"

或者在java code裏面

Button b1 = (Button)findViewById(R.id.vt_button0);
ColorDrawable grDrawble = (ColorDrawable)getResources().getDrawable(R.drawable.green_rectangle);
b1.setBackground(grDrawble);

在實際效果如下

Pro <wbr>Android學習筆記(三):瞭解Android資源(上)

一片顏色不好看,要進行復雜地設置,需要單獨在一個 xml文件中,通過shape來描述。該文件放置在res/drawable/目錄下。下面是my_round_red_retangle.xml的內容

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
    <solid android:color="#f0600000"/> <!-- 這是底層 -->
    <stroke android:width="3dp" android:color="#ffff8080" /> <!-- 這是邊框 -->
    <corners android:radius="13dp"/> <!-- 設置圓角 -->
    <padding android:left="10dp" android:top="10dp" android:bottom="10dp" android:right="10dp" />
</shape>

在java code的使用如下,也可以用android:background="@drawable/my_round_red_rectangle"。Wei:根據Android API Guide,使用的類型是SpanDrawable,如是,會出錯,還是用用GradientDrawable。

Button b2 = (Button)findViewById(R.id.vt_button2);
GradientDrawable roundTangle = (GradientDrawable) getResources().getDrawable(R.drawable.my_round_red_rectangle);
b2.setBackground(roundTangle);

再給出一個例子

Pro <wbr>Android學習筆記(三):瞭解Android資源(上)<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"android:shape="rectangle">
    <gradient android:startColor="#ffff0000"
        android:endColor="#80ff00ff"
        android:angle="45"/>
    <corners android:radius="8dp"/>
</shape>


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章