1. 程式人生 > >Android官方文件—User Interface(Layouts)(概述)

Android官方文件—User Interface(Layouts)(概述)

Layouts


佈局定義使用者介面的可視結構,例如活動或應用程式視窗小部件的UI。您可以通過兩種方式宣告佈局:

  • 以XML格式宣告UI元素。 Android提供了一個簡單的XML詞彙表,它對應於View類和子類,例如小部件和佈局的類。
  • 在執行時例項化佈局元素。您的應用程式可以以程式設計方式建立View和ViewGroup物件(並操縱其屬性)。

Android框架使您可以靈活地使用這些方法中的一種或兩種來宣告和管理應用程式的UI。例如,您可以用XML宣告應用程式的預設佈局,包括將出現在其中的螢幕元素及其屬性。然後,您可以在應用程式中新增程式碼,這些程式碼將在執行時修改螢幕物件的狀態,包括以XML格式宣告的物件。您還應該嘗試使用層次結構檢視器工具來除錯佈局 - 它會顯示佈局屬性值,在模擬器或裝置上除錯時繪製帶有填充/邊距指示符的線框和完整的渲染檢視。layoutopt工具可讓您快速分析佈局和層次結構,以解決效率低下或其他問題。

在XML中宣告UI的優點是,它使您能夠更好地將應用程式的表示與控制其行為的程式碼分開。您的UI描述是應用程式程式碼的外部描述,這意味著您可以修改或修改它,而無需修改原始碼並重新編譯。例如,您可以為不同的螢幕方向,不同的裝置螢幕大小和不同的語言建立XML佈局。此外,使用XML宣告佈局可以更容易地視覺化UI的結構,因此除錯問題更容易。因此,本文件重點介紹如何使用XML宣告佈局。如果您對在執行時例項化View物件感興趣,請參閱ViewGroup和View類引用。

通常,用於宣告UI元素的XML詞彙表緊密遵循類和方法的結構和命名,其中元素名稱對應於類名稱,屬性名稱對應於方法。實際上,對應關係通常是如此直接,以至於您可以猜測XML屬性對應於類方法,或猜測哪個類對應於給定的XML元素。但請注意,並非所有詞彙都相同。在某些情況下,存在輕微的命名差異。例如,EditText元素具有與EditText.setText()對應的text屬性。

  • 您還應該嘗試使用層次結構檢視器工具來除錯佈局 - 它會顯示佈局屬性值,在模擬器或裝置上除錯時繪製帶有填充/邊距指示符的線框和完整的渲染檢視。
  •     layoutopt工具可讓您快速分析佈局和層次結構,以解決效率低下或其他問題。

提示:瞭解有關Common Layout Objects中不同佈局型別的更多資訊。

編寫XML


使用Android的XML詞彙表,您可以快速設計UI佈局及其包含的螢幕元素,就像使用HTML建立網頁一樣 - 使用一系列巢狀元素。

每個佈局檔案必須只包含一個根元素,該元素必須是View或ViewGroup物件。定義根元素後,可以新增其他佈局物件或視窗小部件作為子元素,以逐步構建定義佈局的檢視層次結構。例如,這是一個XML佈局,它使用垂直LinearLayout來儲存TextView和Button:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical" >
    <TextView android:id="@+id/text"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:text="Hello, I am a TextView" />
    <Button android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello, I am a Button" />
</LinearLayout>

在用XML宣告佈局後,在Android專案的res / layout /目錄中儲存副檔名為.xml的檔案,以便正確編譯。

有關佈局XML檔案語法的更多資訊,請參閱“佈局資源”文件。

載入XML資源


載入XML資源

編譯應用程式時,每個XML佈局檔案都會編譯為View資源。您應該在Activity.onCreate()回撥實現中從應用程式程式碼載入佈局資源。這樣做是通過呼叫setContentView(),以以下形式將引用傳遞給您的佈局資源:R.layout.layout_file_name。例如,如果您的XML佈局儲存為main_layout.xml,則可以為您的Activity載入它,如下所示:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main_layout);
}

當您的Activity啟動時,您的Activity中的onCreate()回撥方法由Android框架呼叫(請參閱活動文件中有關生命週期的討論)。

屬性


每個View和ViewGroup物件都支援各種XML屬性。某些屬性特定於View物件(例如,TextView支援textSize屬性),但這些屬性也可由任何可擴充套件此類的View物件繼承。有些對於所有View物件都是通用的,因為它們是從根View類繼承的(就像id屬性一樣)。並且,其他屬性被視為“佈局引數”,它們是描述View物件的某些佈局方向的屬性,由該物件的父ViewGroup物件定義。

ID

任何View物件都可以具有與之關聯的整數ID,以唯一標識樹中的View。編譯應用程式時,此ID被引用為整數,但ID通常在佈局XML檔案中作為字串在id屬性中指定。這是所有View物件(由View類定義)共有的XML屬性,您將經常使用它。 XML標記內的ID語法是:

android:id="@+id/my_button"

字串開頭的at符號(@)表示XML解析器應解析並擴充套件ID字串的其餘部分,並將其標識為ID資源。加號(+)表示這是一個新的資源名稱,必須建立並新增到我們的資源(在R.java檔案中)。 Android框架提供了許多其他ID資源。引用Android資源ID時,您不需要加號,但必須新增android包名稱空間,如下所示:

android:id="@android:id/empty"

有了android包名稱空間,我們現在引用android.R資源類中的ID,而不是本地資源類。

為了建立檢視並從應用程式引用它們,常見的模式是:

1.在佈局檔案中定義檢視/視窗小部件併為其分配唯一的ID:

<Button android:id="@+id/my_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/my_button_text"/>

2.然後建立檢視物件的例項並從佈局中捕獲它(通常在onCreate()方法中):

Button myButton = (Button) findViewById(R.id.my_button);

建立RelativeLayout時,定義檢視物件的ID非常重要。在相對佈局中,兄弟檢視可以相對於另一個兄弟檢視定義其佈局,該檢視由唯一ID引用。

ID在整個樹中不一定是唯一的,但它在您正在搜尋的樹的部分內應該是唯一的(通常可能是整個樹,因此在可能的情況下最好是完全唯一的)。

佈局引數


名為layout_something的XML佈局屬性定義適合其所在ViewGroup的View的佈局引數。

每個ViewGroup類都實現一個擴充套件ViewGroup.LayoutParams的巢狀類。此子類包含定義每個子檢視的大小和位置的屬性型別,適用於檢視組。如圖1所示,父檢視組定義了每個子檢視(包括子檢視組)的佈局引數。

圖1.具有與每個檢視關聯的佈局引數的檢視層次結構的視覺化。

請注意,每個LayoutParams子類都有自己的設定值的語法。每個子元素必須定義適合其父元素的LayoutParams,儘管它也可以為自己的子元素定義不同的LayoutParams。

所有檢視組都包含寬度和高度(layout_width和layout_height),每個檢視都需要定義它們。許多LayoutParams還包括可選的邊距和邊框。

您可以使用精確測量指定寬度和高度,但您可能不希望經常這樣做。更常見的是,您將使用這些常量之一來設定寬度或高度:

  • wrap_content告訴您的檢視將自身大小調整為其內容所需的維度。
  • match_parent告訴您的檢視變得與其父檢視組允許的一樣大。

通常,不建議使用絕對單位(如畫素)指定佈局寬度和高度。相反,使用相對度量(如密度無關畫素單位(dp),wrap_content或match_parent)是一種更好的方法,因為它有助於確保應用程式在各種裝置螢幕大小上正確顯示。可接受的測量型別在可用資源文件中定義。

佈局位置


檢視的幾何形狀是矩形的幾何形狀。檢視具有一個位置,表示為一對左座標和頂座標,以及兩個維度,表示為寬度和高度。位置和尺寸的單位是畫素。

可以通過呼叫getLeft()和getTop()方法來檢索檢視的位置。前者返回表示檢視的矩形的左座標或X座標。後者返回表示檢視的矩形的頂部或Y座標。這些方法都返回檢視相對於其父級的位置。例如,當getLeft()返回20時,這意味著檢視位於其直接父級左邊緣右側20畫素處。

此外,還提供了幾種方便的方法來避免不必要的計算,即getRight()和getBottom()。這些方法返回表示檢視的矩形的右邊和底邊的座標。例如,呼叫getRight()類似於以下計算:getLeft()+ getWidth()。

尺寸,填充和邊距


檢視的大小用寬度和高度表示。檢視實際上具有兩對寬度和高度值。

第一對稱為測量寬度和測量高度。這些維度定義了檢視在其父級中的大小。可以通過呼叫getMeasuredWidth()和getMeasuredHeight()來獲取測量的維度。

第二對簡稱為寬度和高度,有時也稱為繪圖寬度和繪圖高度。這些尺寸定義了螢幕上,繪圖時和佈局後檢視的實際大小。這些值可以但不必與測量的寬度和高度不同。可以通過呼叫getWidth()和getHeight()來獲得寬度和高度。

要測量其尺寸,檢視會考慮其填充。填充以檢視的左,上,右和底部分的畫素表示。填充可用於將檢視的內容偏移特定數量的畫素。例如,左邊的填充為2會將檢視的內容推到左邊緣右側2個畫素。可以使用setPadding(int,int,int,int)方法設定填充,並通過呼叫getPaddingLeft(),getPaddingTop(),getPaddingRight()和getPaddingBottom()來查詢。

即使檢視可以定義填充,它也不會為邊距提供任何支援。但是,檢視組提供了這樣的支援。有關詳細資訊,請參閱ViewGroup和ViewGroup.MarginLayoutParams。

有關尺寸的更多資訊,請參閱尺寸值。

常見佈局


ViewGroup類的每個子類都提供了一種獨特的方式來顯示巢狀在其中的檢視。以下是Android平臺內建的一些更常見的佈局型別。

注意:雖然您可以在另一個佈局中巢狀一個或多個佈局來實現UI設計,但您應該儘量使佈局層次結構儘可能淺。如果巢狀佈局較少,則佈局繪製速度更快(寬檢視層次結構優於深層檢視層次結構)。

Linear Layout

將子項組織為單個水平或垂直行的佈局。如果視窗的長度超過螢幕的長度,它會建立一個滾動條。

Relative Layout

使您可以指定子物件相對於彼此的位置(子B的左側的子A)或父物件的位置(與父物件的頂部對齊)。

Web View

顯示網頁。

使用介面卡構建佈局


當佈局的內容是動態的或未預先確定的時,您可以使用子類AdapterView在執行時使用檢視填充佈局的佈局。 AdapterView類的子類使用介面卡將資料繫結到其佈局。介面卡充當資料來源和AdapterView佈局之間的中間人 - 介面卡檢索資料(來自諸如陣列或資料庫查詢之類的源)並將每個條目轉換為可新增到AdapterView佈局中的檢視。

介面卡支援的常見佈局包括:

List View

顯示滾動的單列列表。

Grid View

顯示列和行的滾動網格。

使用資料填充介面卡檢視

您可以通過將AdapterView例項繫結到介面卡來填充AdapterView(如ListView或GridView),該介面卡從外部源檢索資料並建立表示每個資料條目的View。

Android提供了幾個Adapter的子類,可用於檢索不同型別的資料和構建AdapterView的檢視。兩種最常見的介面卡是:

ArrayAdapter

當資料來源是陣列時,請使用此介面卡。預設情況下,ArrayAdapter通過在每個專案上呼叫toString()並將內容放在TextView中來為每個陣列項建立一個檢視。

例如,如果要在ListView中顯示要顯示的字串陣列,請使用建構函式初始化新的ArrayAdapter,以指定每個字串和字串陣列的佈局:

ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
        android.R.layout.simple_list_item_1, myStringArray);

這個建構函式的引數是:

  • 你的應用上下文
  • 包含陣列中每個字串的TextView的佈局
  • 字串陣列

然後只需在ListView上呼叫setAdapter():

ListView listView = (ListView) findViewById(R.id.listview);
listView.setAdapter(adapter);

要自定義每個專案的外觀,可以覆蓋陣列中物件的toString()方法。或者,要為除TextView之外的其他項建立檢視(例如,如果您希望每個陣列項都有ImageView),請擴充套件ArrayAdapter類並覆蓋getView()以返回每個項所需的檢視型別。

SimpleCursorAdapter

當資料來自Cursor時,請使用此介面卡。使用SimpleCursorAdapter時,必須指定要用於Cursor中每一行的佈局,以及Cursor中的哪些列應插入到佈局的哪些檢視中。例如,如果要建立人員姓名和電話號碼列表,則可以執行一個查詢,該查詢返回包含每個人的行的Cursor以及名稱和數字的列。然後建立一個字串陣列,指定佈局中每個結果所需的Cursor列和一個整數陣列,指定每列應放置的相應檢視:

String[] fromColumns = {ContactsContract.Data.DISPLAY_NAME,
                        ContactsContract.CommonDataKinds.Phone.NUMBER};
int[] toViews = {R.id.display_name, R.id.phone_number};

例項化SimpleCursorAdapter時,傳遞用於每個結果的佈局,包含結果的Cursor,以及這兩個陣列:

SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
        R.layout.person_name_and_number, cursor, fromColumns, toViews, 0);
ListView listView = getListView();
listView.setAdapter(adapter);

然後,SimpleCursorAdapter通過將每個fromColumns項插入相應的toViews檢視,使用提供的佈局為Cursor中的每一行建立一個檢視。

如果在應用程式生命週期中,您更改了介面卡讀取的基礎資料,則應呼叫notifyDataSetChanged()。這將通知附加的檢視,資料已更改,並且應自行重新整理。

處理點選事件

您可以通過實現AdapterView.OnItemClickListener介面來響應AdapterView中每個專案的單擊事件。例如:

// Create a message handling object as an anonymous class.
private OnItemClickListener mMessageClickedHandler = new OnItemClickListener() {
    public void onItemClick(AdapterView parent, View v, int position, long id) {
        // Do something in response to the click
    }
};

listView.setOnItemClickListener(mMessageClickedHandler);