書名: Android應用開發教程(第2版)作者名: 羅文主編本章字數: 4323字更新時間: 2021-10-27 15:03:58
3.2 Android基本組件

07 界面設計
Android應用程序的人機交互界面由很多的Android組件組成,如之前多次使用的TextView、Button等都是Android提供的組件。
本節準備開發一個小型的計算器,用于計算輸入的兩個數的和差積商,第一行用于輸入第一個數,第二行用于選擇四種運算之一,第三行用于輸入第二個數,第四行是一個按鈕,當單擊該按鈕后,將運算結果顯示到第五行。
3.2.1 文本顯示組件
文本顯示(TextView)組件主要用于顯示靜態文本,類似于Java中的Label標簽控件,所不同的是,Android中的TextView組件可以顯示單行文本,也可以顯示多行文本,還可以顯示帶圖像的文本。
AS支持可視化和XML編輯方式添加TextView組件,在布局中添加一個TextView組件,其常見屬性可以在右側的屬性欄中設定,如圖3-11所示。

圖3-11 TextView組件屬性
除了以可視化方法修改屬性之外,還可以直接切換到XML源代碼查看。TextView的配置代碼如下所示。

TextView常用屬性如表3-9所示。
表3-9 TextView常用屬性

(續)

說明:layout_width和layout_height是相對上級元素而確定的布局方式,所以可以設定三個特殊的值,其含義如下。
? fill_parent:強制性地使組件擴展,以填充布局單元內盡可能多的空間。設置一個頂部布局或組件為fill_parent將強制性地讓它布滿整個屏幕。
? wrap_content:設強制性地使視圖擴展以顯示全部內容,布局元素將根據內容更改大小。
? match_parent:Android 2.2中match_parent和fill_parent兩個參數的含義一樣,match_parent更貼切,于是從Android 2.2開始兩者都可以用。如果考慮兼容低版本的使用情況就需要用fill_parent。
大多數程序員更喜歡使用layout_width和layout_height來取代width和height。
Android除了通過XML文件靜態增加TextView之外,還可以使用Java代碼動態產生文本框組件。組件對象創建成功后,可以使用set****()方法設置組件的各種屬性,使用setContentView()方法顯示內容。以下代碼演示了動態構建一個TextView對象并設置其中顯示的文本,最后顯示出來的處理過程,Java代碼如下。

對于使用XML靜態布局方式添加的TextView組件,如果需要動態更改顯示內容,程序可以利用findViewById(id)函數來訪問該元素。findViewById(id)函數從Android 1.0就存在了,是個元老級別的函數,也是非常重要的函數,其功能就是根據提供的組件id獲得組件對象。該函數的返回值是View類型的,所以一般情況下需要進行類型轉換。
不僅對于TextView組件如此,其他的組件對象也基本是通過該方法來進行訪問,如果布局文件中設置TextView的id為textView1,那么可以通過下列代碼將組件上的文字修改為“Hello”。

通常情況下,前兩句可以合并為一行,如下所示。

3.2.2 編輯框組件
AS中的編輯框(EditText)組件用于輸入信息,可以輸入單行文本或多行文本,還可以輸入指定格式的文本(如密碼、電話號碼、E-mail地址等)。其繼承自TextView,所以其大部分屬性與TextView類似。EditText的特色屬性如表3-10所示。
表3-10 EditText的特色屬性

同TextView類似,AS中可通過可視化界面迅速添加EditText組件。不過,Palette視圖中的Text類別中提供了不同輸入功能要求的EditText組件,可以選擇某種樣式以滿足當前的需要,如圖3-12所示。
例如拖入一個標志著數字的組件,其自動生成的XML代碼如下。

可以通過可視化界面或XML代碼方式添加更多的屬性,其中<requestFocus />表示該組件可以接受焦點。一般會增加text屬性顯示默認值(可以是空字符串),增加hint屬性顯示提示信息等,定義代碼如下。

hint屬性顯示效果如圖3-13所示。
對于添加的每一種EditText組件,都可以通過修改android:inputType屬性將其轉變為其他類型的輸入框組件。
也可以使用Java代碼動態處理EditText組件,可以創建、更改輸入的文字等。這里需要特別說明的是,通過getText()方法取得的編輯框中的值都是字符串類型的,即便其中輸入的是形如“123”之類的數字,其返回的仍然是“123”字符串。所以如果需要輸入數字,就需要做相應的類型轉換。
字符串轉換成數值有很多辦法,現在可以先掌握一種:Integer.parseInt(str),其中str為字符串。一般情況下,首先從組件中接收用戶輸入信息,然后利用這個方法進行轉換,參考代碼如下。


圖3-12 Text類別中的EditText組件

圖3-13 hint屬性顯示效果
3.2.3 按鈕組件
按鈕(Button)組件是Android中應用最多的組件之一。與其他組件一樣,Button有兩種添加方式,第一種是在XML中通過<button></button>標記添加,第二種是在程序中直接使用Button類創建對象并添加到視圖中。推薦使用第一種。
在XML中配置Button時,AS同樣支持可視化和代碼方式。在AS中進行可視化配置時,只須在組件視圖的Buttons類中選擇合適的Button拖動到布局中即可。選擇添加的Button,同樣可以在屬性視圖中配置各種屬性,也可在XML代碼視圖中直接修改各種屬性。例如以下的Button示例:

Button組件一般用作發布命令,發布單擊命令后執行對應的程序,這個程序一般被稱之為“單擊事件響應程序”。在Android中,一般首先為按鈕注冊單擊監聽事件,監視是否有單擊事件發生于該按鈕上,如果有,則去執行對應的單擊事件響應程序。
為按鈕綁定監聽程序有兩種方法,一種是在Activity的onCreate()方法中完成,示例代碼如下。

另一種方法是在Activity中編寫一個包含View類型參數并且將要觸發的處理代碼放在其中,然后在布局文件中給Button添加android:onClick屬性指定對應的方法名。例如在Activity中編寫一個方法如下。

然后在布局文件中,給Button添加屬性android:onClick="myClick"實現給按鈕添加監聽器。
3.2.4 單選按鈕/單選按鈕組組件
默認情況下,單選按鈕(RadioButton)組件一般呈現為一個圓形圖標,旁邊放置一些說明性文字。使用時,將多個單選按鈕放在一組中,它們一起被稱為單選按鈕組(RadioGroup)組件。對于單選按鈕,其狀態可以是“選中”或“未選中”。初始時通過checked屬性可以設置單選按鈕的狀態。同一組中的單選按鈕具備排他性,組中某個單選按鈕被選中,組中其他單選按鈕就會被取消選擇。
單選按鈕繼承自Button類,所以單選按鈕可以支持Button的所有屬性。同其他組件類似,在Android中有兩種方式添加單選按鈕組件,一種是在XML布局文件中通過<RadioButton>標記添加,另一種是在Java代碼中通過創建RadioButton類對象添加。推薦使用XML布局文件配置方式。
在AS中,XML布局文件配置方式依然支持可視化和代碼操作方式,具體操作模式與其他組件類似,最后可得到如下所示的XML代碼。

通常情況下,單選按鈕一般放在RadioGroup組件中,在XML文件中添加RadioGroup的示例代碼如下。

RadioGroup組件有一個特別的屬性orientation,通過將該屬性設定為horizental或vertical可以確定該組中的各單選按鈕的排列方式為水平還是垂直。
對于用戶選中情況的判定,同按鈕按下與否的判定類似,同樣通過監聽實現。對于單選按鈕組而言,需要監聽的是“選中的單選項目是否發生變化”這個事件,即setOnCheckedChange Listener()。在onCreate()方法中添加如下代碼。


3.2.5 復選框組件
默認情況下,復選框(CheckBox)組件顯示一個方塊圖標,在該圖標旁邊放置一些說明性文字。復選框的使用與單選按鈕類似,所不同的是,單選按鈕存在分組的情況,而復選框是獨立操作的,可以多選。
在AS中,仍然提供兩種方式添加復選框組件,一種是在XML布局文件中通過<CheckBox>標記添加,另一種是使用Java代碼通過創建CheckBox類對象添加。推薦XML布局文件方式,在XML布局文件中添加CheckBox的示例代碼如下。

復選框通過Checked屬性確定是否被選中,該類有兩個常用的方法。
? isChecked():獲知當前狀態,該方法返回true表示當前復選框為選中狀態,否則為未選中。
? setChecked():通過參數true或false設置復選框為選中或未選中狀態。
由于復選框可以多選,因此為了確定用戶是否選擇了某一項,需要為每個選項都添加事件監聽器。例如為checkBox1添加如下事件監聽器代碼。

3.2.6 圖像視圖組件
圖像視圖(ImageView)組件用于在界面中顯示任何的Drawable對象,通常用來顯示圖片。在Android中,有兩種方法添加圖像視圖,第一種是通過在XML布局文件中使用<ImageView>標記添加,第二種是在Java代碼中通過創建ImageView類對象添加。推薦采用第一種方法添加。
使用ImageView組件顯示圖片時,通常可以將要顯示的圖片放置在res\drawable目錄中,然后應用類似下面的代碼將圖像顯示在布局管理器中(通過android:src屬性設置圖片)。

ImageView組件常用XML屬性如表3-11所示。
表3-11 ImageView組件常用XML屬性

其中android:scaleType屬性設置填充方式,其可選值說明如表3-12所示。
表3-12 android:scaleType屬性的可選值

3.2.7 滾動視圖組件
滾動視圖(ScrollView)組件用于為其他組件添加滾動條。在默認的情況下,由于Android的布局管理器沒有提供滾動屏幕的功能,當窗體中的內容較多而一屏顯示不下時,超出的部分用戶將看不到,這時就需要使用ScrollView組件了。
在滾動視圖中可以放入任何類型的組件,但是只能放一個,如果需要放置多個組件,可以先在滾動視圖中放置一個布局管理器,再在布局管理器中放置其他的組件。ScrollView組件只支持垂直滾動,如果要實現水平滾動,需要使用水平滾動視圖(HorizontalScrollView)。
同其他組件類似,Android中可以使用XML布局文件和Java代碼創建對象兩種方法添加滾動視圖。推薦使用XML布局文件方法,示例XML代碼如下。

3.2.8 日期/時間選擇器組件
為了讓用戶獲取日期和時間,Android提供了日期/時間選擇器(DatePicker/TimePicker)組件。用戶可以在XML布局文件中直接添加這兩個組件到界面中。AS同樣提供了XML布局文件和Java代碼創建對象兩種方法添加日期/時間選擇器,XML代碼示例如下。

為了在程序中獲取用戶選擇的日期和時間,還需要為組件添加事件監聽器。其中DataPicker組件對應的事件監聽器是OnDateChangedListener,TimePicker組件對應的事件監聽器是OnTimeChangedListener。具體使用與其他組件類似,這里不再贅述。
3.2.9 列表選擇框組件
列表選擇框(Spinner)組件相當于Java中的下拉列表框,用于提供一系列可選擇的列表項供用戶選擇,從而方便用戶。
Android中依然可以采用XML布局文件和Java代碼創建對象兩種方法添加這個組件,推薦使用XML布局方式。Spinner通過修改spinnerMode屬性提供下拉或彈出對話框的選擇形式,備選內容可以通過entries屬性引用定義的數組資源,示例如下。

3.2.10 列表視圖組件
列表視圖(ListView)組件以垂直的形式列出需要顯示的列表項,例如顯示系統設置項或功能列表等。要在程序中使用列表視圖組件除了上述采用XML布局文件和Java代碼創建對象兩種方法外,還可以通過繼承ListActivity類來實現。列表視圖支持的XML屬性如表3-13所示。
表3-13 列表視圖支持的XML屬性

(續)

在XML布局中直接添加列表視圖的示例代碼如下。

3.2.11 實例2:簡易計算器
1.新建項目,增添組件
在AS中新建項目,應用程序命名為“簡易計算器”,項目命名為“ch03_02”,其他項取默認值。
為了實現數據的輸入,需要使用EditText組件用于輸入信息;RadioGroup和RadioButton組件用于4種運算方法的選擇;Button組件用于確定運算;TextView組件用于顯示結果。各組件及其功能見表3-14。
表3-14 各組件及其功能

為了取得用于選擇的運算符,需要對單選按鈕進行監聽,即需要重寫調用單選按鈕的setOnCheckedChangeListener方法。

onCheckedChanged()方法有兩個參數,第一個參數是對于單選按鈕組的引用,第二個參數則是當前選中單選按鈕的id。在onCheckedChanged()中獲取用戶當前所選運算符。一般可以在類MainActivity中增加一個記錄當前運算符的字符串opr,其值與單選按鈕默認選中的“+”保持一致,以后只要單選按鈕組發生變化,opr同步進行變化。
然后為按鈕增加單擊響應事件。

2.設計布局
考慮到上述組件由上到下依次排列,所以首選線性布局方式,在其中添加相應組件。為了不造成混淆,字符串沒有專門定義字符串資源,在真正進行項目實施的時候,需要注意選擇字符串等相關資源。
布局文件activity.xml的內容如下。


3.參考代碼


這里需要提醒的是,在比較字符串是否相同時,不能直接使用“==”,而應該調用字符串對象的equals()方法。運行程序,選擇不同運算符,加法結果如圖3-14所示。

圖3-14 加法結果
注意:做除法運算時,如25/3=8,會有些誤差。這是程序中的商僅用整數來記錄導致的。另外,程序并沒有對除數為0、缺失操作數等例外情況進行處理,讀者可以自行修改、調整程序以完成這些功能,否則非法操作就可能導致程序崩潰。