第6章 建立Android使用介面 6-1 介面元件的基礎 6-2 Android的事件處理 6-3 按鈕元件 6-4 文字元件 6-5 選擇元件 6-6 圖片顯示元件
6-1 介面元件的基礎 6-1-1 View與ViewGroup類別 6-1-2 介面元件的類別架構 6-1-3 Android使用的尺寸單位
6-1-1 View與ViewGroup類別 – 說明 介面元件(Widgets,可稱為View物件):正確的說,Android的介面元件是Widget;不是View,Widget是View的子類別,就是一些與使用者互動的圖形介面元件,例如:Button和EditText元件等。 版面配置類別(Layout Class,可稱為ViewGroup物件):ViewGroup抽象類別是View的子類別,它是第5章版面配置類別的父類別,一種看不見的容器類別,用來組織其他介面元件和ViewGroup物件。
6-1-1 View與ViewGroup類別 – 樹狀結構 Android應用程式的使用介面,以Java程式碼的角度來看,在活動視窗的使用介面是一棵View和ViewGroup物件組成的樹狀結構,如下圖所示:
6-1-2 介面元件的類別架構 View類別是所有使用介面元件的基礎類別,在本章說明的TextView、Button、ImageButton、RadioButton和ImageView等類別都是它的子類別(屬於android.widget套件),其類別架構如下圖所示:
6-1-3 Android使用的尺寸單位 在Android介面元件的XML屬性指定尺寸時,除了第5章fill_parent、match_parent和wrap_content常數外,還可以指定元件實際的尺寸,可以使用的單位說明,如下表所示: 單位 說明 dp或dip Desity-independent Pixel的簡稱,一英吋實際的螢幕尺寸相當於160dp,這是Android建議使用的尺寸單位 sp Scale-independent Pixel,類似dp,建議使用在字型尺寸 pt 一點等於1/72英吋 px 實際螢幕上的點,Android不建議使用此尺寸單位
6-2 Android的事件處理 6-2-1 事件處理的基礎 6-2-2 認識介面元件的android:id屬性 6-2-3 建立事件處理方法
6-2-1 事件處理的基礎 「事件」(Event)是在執行Android應用程式時,手指操作介面元件或鍵盤時所觸發的一些動作。Android事件處理是一種「委託事件處理模型」(Delegation Event Model),分為「事件來源」(Event Source)和處理事件的「傾聽者」(Listener)物件,如下圖所示:
6-2-2 認識介面元件的android:id屬性 – 說明 android:id屬性是在使用介面中找到指定介面元件的索引,如果需要撰寫Java程式碼更改介面元件的屬性,或建立事件處理時,記得一定要指定此屬性值,例如:建立Button元件的事件處理方法。
6-2-2 認識介面元件的android:id屬性– android:id屬性值的命名原則 在XML標籤指定的android:id屬性值,Android Studio會自動編譯成Java語言的類別常數,所以,屬性值就是Java語言的變數,需要遵守變數的命名原則,例如:第5-6-1節的activity_main.xml,我們替Button元件命名,如下所示: <Button android:id="@+id/button" android:text ="請按我" ….../> 上述Button元件名稱是button,在習慣上,我們都是以小寫字母開頭來命名。在Android Studio專案參考此元件的寫法,如下所示: XML文件:使用@id/button或@android:id/button來參考此元件。 Java程式碼:使用R.id.button參考此元件,因為Android Studio已經自動編譯成R.java類別檔。
6-2-2 認識介面元件的android:id屬性 - android:id屬性與R.java 筆者準備使用第5-6-1節的Button元件為例,進一步說明如何在Java程式碼找到Button元件,如此才可以建立Button元件的事件處理。 請參考第2-5-3節的說明,在Android Studio專案Ch5_6_1開啟R.java檔案(只列出id內層類別),如下所示: public final class R { …… public static final class id { ...... public static final int button=0x7f080040; }
6-2-2 認識介面元件的android:id屬性 – 找出Button元件 在Java程式碼可以使用類別常數來找出Button元件button,如下所示: Button btn1 = (Button) findViewById(R.id.button); findViewById()方法參數是R.id.button類別常數(參考上述程式碼的粗體字),從資源索引檔R.java可以取得Button元件button的常數值為0x7f0b0055。
6-2-3 建立事件處理方法 – 方法一 在<Button>標籤的andorid:onClick屬性指定事件處理方法名稱(詳見第2-3節的Ch2_3專案,這是Android專屬寫法),以此例是button1_Click()方法,如下所示: <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="請按我" android:onClick=“button1_Click”/> 直接設定
6-2-3 建立事件處理方法 – 方法二 使用匿名內層類別建立傾聽者物件來實作介面方法,並且將它指定給btn1Listener物件變數,以按鈕的Click事件來說,就是實作OnClickListener介面的onClick()方法來處理Click事件(詳見第6-3-1節),如下所示: btn1.setOnClickListener(btn1Listener); ….. View.OnClickListener btn1Listener = new View.OnClickListener() { public void onClick(View v) { } };
6-2-3 建立事件處理方法 – 方法三 在setOnClickListener()方法中使用匿名內層類別建立傾聽者物件來實作介面方法(詳見第6-3-2節),此種寫法就不需要將建立的傾聽者物件指定給物件變數(但只能單獨給此物件使用),如下所示: imgBtn1.setOnClickListener( new View.OnClickListener(){ public void onClick(View v) { ….. } });
6-2-3 建立事件處理方法 – 方法四 活動繼承Activity類別實作事件處理介面,此時Activity物件本身就是一個處理事件的傾聽者物件(詳見第6-3-3節),如下所示: public class MainActivity extends AppCompatActivity { implements OnCheckedChangeListener { public void onCreate(Bundle savedInstanceState) { ….. toggle.setOnCheckedChangeListener(this); } …. public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { ……
6-2-3 建立事件處理方法 – 方法五 使用具名內層類別實作事件處理介面來建立傾聽者物件,類似繼承Activity類別實作事件處理介面,只是多宣告一個內層類別來實作事件處理介面,而不是使用Activity類別本身來實作,如下所示: class MyActivity extends AppCompatActivity { public void onCreate(Bundle savedInstanceState) { ….. MyListener listener = new MyListener(); button1.setOnClickListener(listener); } class MyListener implements View.OnClickListener() { public void onClick(View v) {
6-3 按鈕元件 6-3-1 Button文字按鈕元件 6-3-2 ImageButton圖片按鈕元件 6-3-3 ToggleButton切換按鈕元件
6-3 按鈕元件 按鈕(Button)元件是Android使用介面中十分重要的介面元件,它是實際執行功能的介面元件,也就是觸發事件的元件。在日常生活中的按鈕也隨處可見,例如:門鈴和遊戲控制器的按鈕,按一下可以響起門鈴聲,或發射子彈射擊。 在Android使用介面上建立的按鈕可以分為三種:文字按鈕、圖形按鈕和切換按鈕,即Button、ImageButton和ToggleButton元件,在之後的三小節將依序說明這三種元件。
6-3-1 Button文字按鈕元件 – 標籤 Button元件是一種文字按鈕,因為按鈕的標題是文字內容,可以觸發Click事件執行事件處理方法(即onClick事件處理方法),例如:在輸入資料後,按下按鈕顯示計算結果或更改屬性等操作。 在版面配置資源的XML文件是使用<Button>標籤宣告在使用介面建立Button元件,如下所示: <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="100dp" android:text="樸克牌1"/>
6-3-1 Button文字按鈕元件 – 指定Button元件的傾聽者物件 在Acitvity類別的onCreate()方法需要指定Button元件的傾聽者物件,如下所示: Button btn = (Button) findViewById(R.id.button); btn.setOnClickListener(btnListener); 上述程式碼先使用findViewById()方法取得名為button(即android:id屬性值)的Button元件,然後使用setOnClickListener()方法註冊傾聽者物件為參數的btnListener物件。
6-3-1 Button文字按鈕元件 – 建立傾聽者物件 在Java程式碼可以使用匿名內層類別建立傾聽者物件,此物件的onClick()方法負責處理Button元件產生的Click事件,如下所示: View.OnClickListener btnListener = new View.OnClickListener() { public void onClick(View v) { ….. } };
6-3-1 Button文字按鈕元件 – 圖例
6-3-2 ImageButton圖片按鈕元件 – 標籤 ImageButton元件的圖片按鈕功能和文字按鈕相同,只是顯示外觀是圖片,它是第6-6節ImageView元件的子類別。 在版面配置資源的XML文件是使用<ImageButton>標籤宣告在使用介面建立ImageButton元件,如下所示: <ImageButton android:id="@+id/imgBtn2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="5dp" android:layout_marginLeft="5dp" android:src="@drawable/back"/>
6-3-2 ImageButton圖形按鈕元件 – 建立傾聽者物件 本節傾聽者物件是使用匿名內層類別來建立,但是沒有指定給物件變數,它是在setOnClickListener()方法直接宣告匿名內層類別實作此介面來建立傾聽者物件,如下所示: imgBtn1.setOnClickListener( new View.OnClickListener(){ public void onClick(View v) { imgBtn1.setImageResource(R.drawable.h11); } });
6-3-2 ImageButton圖形按鈕元件 – 圖例
6-3-3 ToggleButton切換按鈕元件 – 標籤 在版面配置資源的XML文件是使用<ToggleButton>標籤宣告在使用介面建立ToggleButton元件,如下所示: <ToggleButton android:id="@+id/toggleBtn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textOff="直向" android:textOn="橫向"/>
6-3-3 ToggleButton切換按鈕元件 – CheckedChanged事件 當使用者按一下ToggleButton按鈕,不論是開或關,都會觸發CheckedChanged事件,類別需要實作OnCheckedChangeListener介面,才能註冊為此事件的傾聽者物件。
6-3-3 ToggleButton切換按鈕元件 – 將活動類別自己建立成傾聽者物件 我們可以直接將活動類別自己建立成傾聽者物件,此時的類別需要實作OnCheckedChangeListener介面,如下所示: public class MainActivity extends AppCompatActivity implements OnCheckedChangeListener { public void onCreate(Bundle savedInstanceState) { …… toggle.setOnCheckedChangeListener(this); } public void onCheckedChanged( CompoundButton buttonView, boolean isChecked) { if (isChecked) { };
6-3-3 ToggleButton切換按鈕元件 – 圖例
6-4 文字元件 - 說明 Android使用介面的文字元件主要有兩種:TextView和EditText元件,一個可以顯示文字內容;一個是用來輸入文字內容。對比應用程式的輸出入,TextView是程式輸出;EditText是程式輸入。
6-4 文字元件 - TextView元件1 TextView元件就是Windows作業系統的標籤控制項,它是一種資料輸出元件,可以顯示程式執行結果,例如:按下Button元件後,在TextView元件顯示數學運算結果。在版面配置資源的XML文件是使用<TextView>標籤來宣告,如下所示: <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="身高(公分):"/>
6-4 文字元件 - TextView元件2 在Android Studio的Design設計編輯器是使用【Widgets】區段下的【TextView】來新增TextView元件。
6-4 文字元件 - EditText元件1 EditText元件是TextView元件的子類別,可以讓使用者以鍵盤輸入程式所需的資料。例如:姓名、帳號和電話等,在版面配置資源的XML文件是使用<EditText>標籤來宣告,如下所示: <EditText android:id="@+id/txtHeight" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="number"/>
6-4 文字元件 - EditText元件2 android:inputType屬性值的常用輸入類型說明,如下表所示: 屬性值 說明 none 唯讀 text 一般文字 textUri URL網址 number 整數 numberSigned 有符號整數 numberDecimal 浮點數 phone 電話號碼 datetime 日期/時間 date 日期 time 時間 textMultiLine 多行文字 textEmailAddress 電子郵件地址 textPassword 密碼 textVisiblePassword 可見密碼
6-4 文字元件 - EditText元件3 在Android Studio介面設計工具的【Text Fields】區段提供上表大多數輸入類型的EditText元件,如右圖所示:
6-5 選擇元件 6-5-1 CheckBox核取方塊元件 6-5-2 RadioGroup與RadioButton選項按鈕元件
6-5-1 CheckBox核取方塊元件 – 說明 CheckBox元件是一個開關,可以讓使用者選擇是否開啟功能或設定某些參數。如果使用介面同時擁有多個CheckBox元件,每一個元件都是獨立選項,換句話說,CheckBox元件允許複選。
6-5-1 CheckBox核取方塊元件 – 標籤 在版面配置資源XML文件是使用<CheckBox>標籤宣告在使用介面建立CheckBox元件,如下所示: <CheckBox android:id="@+id/chkOriginal" android:text="原味披薩 $250" android:checked="true" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
6-5-1 CheckBox核取方塊元件 – Android Studio介面設計工具 在Android Studio介面設計工具提供名為【CheckBox】元件來新增CheckBox元件。
6-5-1 CheckBox核取方塊元件 – 取得使用者的選擇 CheckBox元件擁有2個狀態:勾選的【核取】和沒有勾選的【未核取】,核取的CheckBox元件,在小方塊中會顯示小勾號。在Java程式碼可以呼叫方法檢查是否勾選CheckBox元件,如下所示: if (original.isChecked()) amount += 250 * quantity; 上述CheckBox元件original呼叫isChecked()方法來檢查是否核取,傳回true表示核取;反之為沒有核取。
6-5-2 RadioGroup與RadioButton選項按鈕元件 - 說明 RadioButton元件是二選一或多選一的選擇題,使用者可以在一組RadioButton元件(使用RadioGroup來群組)中選取一個選項,這是一種單選題。
6-5-2 RadioGroup與RadioButton選項按鈕元件-標籤 因為RadioButton元件是一組多個,所以在版面配置資源的XML文件需要使用<RadioGroup>和<RadioButton>標籤宣告在使用介面建立RadioButton元件,如下所示: <RadioGroup android:id="@+id/rdgSteak" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <RadioButton android:id="@+id/rdbRare" android:layout_width="wrap_content" android:text="三分熟"/> …… <RadioButton android:id="@+id/rdbWellDone" android:text="全熟"/> </RadioGroup>
6-5-2 RadioGroup與RadioButton選項按鈕元件- Android Studio介面設計工具 在Android Studio介面設計工具需要先新增【Containers】區段的【RadioGroup】元件後,就可以在之中新增多個【Widgets】區段的【RadioButton】元件來建立一組RadioButton元件。
6-5-2 RadioGroup與RadioButton選項按鈕元件- 取得使用者的選擇1 RadioButton元件的各選項是互斥的,只能選取其中一個選項。如果選取,在小圓圈中顯示實心圓,沒有選取是空心。如同CheckBox元件,我們可以呼叫isChecked()方法來判斷是否選取該選項按鈕。
6-5-2 RadioGroup與RadioButton選項按鈕元件- 取得使用者的選擇2 另一種方式是使用CheckedChanged事件,當使用者更改選擇時,就使用實作RadioGroup.OnCheckedChangeListener介面的傾聽者物件來處理,擁有一個onCheckedChanged()介面方法,如下所示: public void onCheckedChanged( RadioGroup group, int checkedId) { if (checkedId == rdb01.getId()) output.setText(rdb01.getText()); else if (checkedId == rdb02.getId()) output.setText(rdb02.getText()); else if (checkedId == rdb03.getId()) output.setText(rdb03.getText()); else output.setText(rdb04.getText()); }
6-6 圖片顯示元件 – 說明 ImageView元件是一種顯示圖片的元件,例如:圖示或照片等,可以用來顯示Android專案圖形資源的圖檔,例如:PNG、JPG和GIF等格式的圖檔。
6-6 圖片顯示元件 – 標籤 在版面配置資源XML文件是使用<ImageView>標籤宣告在使用介面建立ImageView元件,如下所示: <ImageView android:id="@+id/image" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:src="@drawable/rabbit"/>
6-6 圖片顯示元件 – Android Studio介面設計工具
6-6 圖片顯示元件 – 在Java程式碼更改顯示的圖片 在Java程式碼找到使用介面中的ImageView元件後,就可以呼叫setImageResource()方法更改顯示的圖形資源,如下所示: image.setImageResource(R.drawable.elephant); 上述setImageResource()方法的參數是R.drawable.elephant,它就是「app/src/main/res/drawable」目錄下名為elephant.png的圖形檔案,進一步說明請參閱第8-4節。
直接選用SD Card上之圖檔 ImageView img =(ImageView) this.findViewById(R.); Bitmap bmp= BitmapFactory.decodeFile(“sdcard/bg.jpg”); Img.setImageBitmap(bm p);
End