CH7 佈局、按鈕與文字編輯元件
視圖與視圖容器 Android應用程式透過視圖與視圖容器建立起活動特有的使用者介面,並以視圖及其對應的一些事件達成與使用者互動的目的。
一、使用者介面的組成 Android使用者介面是以視圖(View)類別與視圖容器(ViewGroup)類別所建立的階層式樹狀結構(即使用者介面的佈局),視圖及視圖容器類別都是源自於「android.view.View」類別的子類別。 視圖類似元件樹中的葉子,是使用者介面階層真正互動的元件。 視圖容器則如同元件樹中枝與根的部分,它沒有可見的外觀,也不具有互動的能力,只是作為視圖元件的儲存容器。
佈局 (Layout) 是ViewGroup類別的子類別,規劃了視圖元件在介面的排列方式,元件樹的根一定是Layout。
在XML文件檔中,元件的屬性是以「android:屬性名稱=”屬性值”」定義。
二、Android應用程式人機介面佈局 佈局規劃了視圖元件在人機介面的排列方式,可以透過Eclipse佈局編輯器以圖形方式編輯,或直接在XML佈局檔中用XML標籤建立。 Android共提供了6種佈局方式: Linear Layout(線性佈局) Table Layout(表格式佈局) Relative Layout(相對位置佈局) Absolute Layout(絕對位置佈局) Frame Layout(框架式佈局) Grid Layout(格點式佈局) 。
Linear Layout(android.widget.LinearLayout) 所有元件均以線性排列方式對齊(垂直或水平,以「orientation」屬性設定,屬性值可以是horizontal或vertical;預設為horizontal)。 常用的屬性如下: gravity:設定元件內容在其範圍內該如何定位。 orientation:設定下層子元件以水平或垂直方向排列。 layout_gravity:設定元件在其上層X、Y軸定位方式。 layout_weight:佈局權重,設定在線性佈局中此視圖可以分配到的剩餘空間的比率。 Table Layout(android.widget.TableLayout) 將整個使用者介面分成數列,而每一列又分成數個儲存格(cell),每一個儲存格可以放置視圖元件或其他佈局,形成巢狀佈局的規劃。
Relative Layout(android.widget.RelativeLayout) 規劃元件和元件之間的相對位置,這些位置可以是屬性「layout_above」(置於指定元件上方)、「layout_below」(置於指定元件下方)、「layout_toLeftOf」(置於指定元件左側)、「layout_toRightOf」(置於指定元件右側),也可以用「layout_alignBaseline」屬性設定與視圖底部對齊,這5個屬性設定的值必須是佈局中另一個視圖的識別碼,即另一個視圖的「android:id」屬性。 Absolute Layout(android.widget.AbsoluteLayout) 明確的指定各元件在介面的位置(以「layout_x」與「layout_y」屬性設定視圖的橫向與縱向座標) 。
Frame Layout(android.widget.FrameLayout) Frame Layout與「TabHost」和「TabWidget」配合,則可以建立具有「Tab」的使用者介面。
三、Grid Layout佈局(android.widget.GridLayout) Android 4.0(API level 14,Ice Cream Sandwich)開始新增了格點式佈局(Grid Layout),它的目的是取代原有的線性與相對位置佈局。 Layout將使用者介面劃分為不同的列、行、與儲存格(cell),下層的元件可以採自動方式,依序放入儲存格中;或是以指定行列索引的方式(利用元件的「layout_column」與「layout_row」屬性),將元件置於指定的儲存格內。
其餘常用屬性說明如下: 以下4個屬性是用於元件(儲存格)上: columnCount:自動將元件放入儲存格時,所建立一列的最大的行數。 rowCount:自動將元件放入儲存格時,所建立最大的列數。 orientation:可設定為「horizontal」或「vertical」,指定自動將元件放入儲存格時,是以列為主或以行為主。 以下4個屬性是用於元件(儲存格)上: layout_column:指定行索引,從0開始。 layout_row:指定列索引,從0開始。
Android 4.0版另外也提供一個新的視圖元件「Space」,它是用以在元件和元件之間保留空間。 layout_columnSpan:儲存格橫向佔用的行數。 layout_rowSpan:儲存格縱向佔用的列數。 Android 4.0版另外也提供一個新的視圖元件「Space」,它是用以在元件和元件之間保留空間。 注意:使用GridLayout與Sapce時,專案的「Minimun Required SDK」需設定為API 14以上。
佈局範例程式 <RelativeLayout 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:context=".MainActivity" > <TextView android:id="@+id/luckyNumber" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:layout_marginTop="85dp"
android:hint="請先輸入幸運號碼上限" android:textColor="#ff0000" android:textSize="24sp" /> <EditText android:id="@+id/maxNumberTxt" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/luckyNumber" android:layout_centerHorizontal="true" android:layout_marginTop="72dp" android:ems="10" android:inputType="number" android:text="0" >
<requestFocus /> </EditText> <Button android:id="@+id/sureBtn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/maxNumberTxt" android:layout_centerHorizontal="true" android:layout_marginTop="75dp" android:text="確定" /> </RelativeLayout>
四、常用元件 TextView EditText Button
TextView 主要的作用是顯示資訊。 autoLink:屬性;設定是否要匹配找出合於指定格式內容,並將辨識成功的內容轉換成超連結文字。 hint:屬性;設定當尚未設定內容時,預設顯示的提示資訊。 text:屬性;所要顯示的內容。 textColor:屬性;設定顯示內容的顏色。 textSize:屬性;設定顯示文字大小。 textStyle:屬性;設定顯示文字字體。 typeface:屬性;設定顯示文字字型。
singleLine:屬性;是否限定文字超過元件寬度時,不自動分行,而以單行可捲動方式顯示。 addTextChangedListener(TextWatcher):方法;將TextWatcher物件加入一清單中,當內容改變時會呼叫它的方法。 getHint():方法;傳回未設定內容時,預設顯示的提示資訊。 getText():方法;傳回元件顯示的文字內容。 length():方法;傳回元件顯示內容的字元數。 setHint():方法;設定當尚未設定內容時,顯示的提示資訊。 setText():方法;設定元件顯示內容。
EditText EditText源自於TextView,因此擁有TextView的所有屬性與方法,它主要目的就是提供使用者輸入介面。 digitals:屬性;列舉出所有輸入可以接受的字元(文、數字均可)。 inputType:屬性;設定可以輸入的資料型式。 numeric:屬性;指定輸入數字。 password:屬性;遮蔽實際輸入的顯示字元。 onKeyDown(int, KeyEvent):方法;預設KeyEvent.Callback.onKeyDown()方法的實作。
onKeyUp(int, KeyEvent):方法;預設KeyEvent.Callback.onKeyUp()方法的實作。 onTouchEvent(MotionEvent):方法;實作此方法處理觸控螢幕的運動事件。 onTrackballEvent(MotionEvent):方法;實作此方法處理軌跡球運動事件。 onWindowFocusChanged(boolean):方法;當含此元件的介面獲得或失去焦點時呼叫此方法。 setKeyListener(KeyListener):方法;設定此元件使用的按鍵事件偵聽器。
Button Button也源自於TextView,是最簡單與直覺的互動元件。 findViewById():方法;以指定的識別碼搜尋子元件。 findViewWithTag(Object):方法;以指定的標籤搜尋子元件。 getId():方法;傳回本身的識別碼。 getParent():方法;傳回對上層父元件參考。
isPressed():方法;傳回本身目前是否處於被壓下狀態。 onClick():方法;當本身被敲擊時呼叫此方法。 setOnClickListener(OnClickListener):方法;登錄當本身被敲擊時所要求的回呼方法。
五、產生幸運數字應用範例 建立活動佈局並提供視圖的目的是要應用程式能與使用者互動,對Android應用程式的互動是藉由事件處理機制完成。 在此機制下可以分成3個要項:事件、事件來源與事件偵測。 事件大多由使用者的動作產生。 事件來源是指接受動作轉而發出對應事件的目標元件。 事件偵測,則是利用事件偵聽器完成。
本範例將建立一個簡單的應用程式,它的目的是為使用者產生一個1~指定範圍的數字,做為使用者的幸運數字。 處理事件一般需要3個步驟: 從介面建立目標事件偵聽器物件。 登錄目標事件偵聽器。 實作事件處理方法。 本範例將建立一個簡單的應用程式,它的目的是為使用者產生一個1~指定範圍的數字,做為使用者的幸運數字。 步驟請參考原書。
MainActivity.java 程式架構 宣告專案名存放路徑 package com.example.luckynumber; 引入參考類別 import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView;
宣告及定義類別 public class MainActivity extends Activity { } 宣告參考至視圖元件欄位類別定義 定義 onCreate方法 建立目標事件偵聽事件 OnClickListener 登錄目標事件偵聽器 實作事件處理方法 onClick() }
範例程式 package com.example.luckynumber; import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView;
public class MainActivity extends Activity { //宣告參考至視圖元件欄位 private TextView luckyNumber; private EditText maxNumberTxt; private Button sureBtn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //令各欄為參考到對應視圖 luckyNumber=(TextView) findViewById(R.id.luckyNumber); maxNumberTxt=(EditText) findViewById(R.id.maxNumberTxt); sureBtn=(Button) findViewById(R.id.sureBtn);
//設定按鈕onClick事件偵聽器 sureBtn.setOnClickListener(sureBtnOnClick); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.activity_main, menu); return true;
//建立OnClickListener物件(事件偵聽器),並實作onClick()方法以處理onClick事件 private Button.OnClickListener sureBtnOnClick= new Button.OnClickListener() { public void onClick(View v) { int max = Integer.parseInt(maxNumberTxt.getText().toString()); if(max > 0) luckyNumber.setText("你的幸運數字是:"+String.valueOf((int)(Math.random()*max+1))); } };