官术网_书友最值得收藏!

2.7 Android應用界面

Android應用界面系統,即Android UI(User Interface)系統是Android應用框架最核心的內容之一,也是開發者們需要重點掌握的內容。如果我們把Android應用也分為前后端兩部分的話,那么之前介紹的核心要點和四大組件等都屬于后端,而Android UI系統則屬于前端。后端保證應用的穩定運行,而前端則決定應用的外觀和體驗。對于一個優秀的Android應用來說,漂亮的外觀和流暢的體驗是必不可少的。接下來,我們便來學習Android外觀系統的知識。

在2.3.3節中我們已經簡單介紹了Android應用框架中的外觀系統(View System),也就是Android UI系統的基礎知識。我們知道了對于Android應用來說,最重要的兩個基礎類就是View和ViewGroup:View是絕大部分UI組件的基礎類,而ViewGroup則是所有Layout布局組件的基類。當然,ViewGroup也是View的子類。相關類庫的樹形結構如下。

java.lang.Object
|- android.view.View
 |- android.view.ViewGroup
  |- android.widget.FrameLayout
  |- android.widget.LinearLayout
     |- android.widget.TableLayout
  |- android.widget.RelativeLayout
  |- android.widget.AbsoluteLayout

本節將重點介紹Android應用(非游戲)使用的UI系統。一般來說,我們都使用XML格式的模板文件來書寫對應的UI界面,當然,這種做法也比較符合MVC的設計思想。另外,由于UI模板獨立于邏輯之外,界面設計師們就可以更加專注于他們自己的事情。在模板文件中,每個UI控件都由對應的XML標簽來表示,具體的控件標簽見表2-3,大家可以回顧一下。

2.7.1 控件屬性

我們知道Android UI系統給我們提供了豐富多彩的控件,比如TextView、Button、TextView、EditText、ListView、CheckBox、RadioButton等,具體如表2-3所示。我們可以使用這些不同功能的控件來完成各種各樣用戶界面的需求。那么控件本身的屬性應該如何設置呢?實際上,每個UI控件都有很多的屬性可供我們選擇,我們一般都是通過設置這些屬性來設置UI控件的外觀、位置等。代碼清單2-17中就是使用XML來表示文本框控件(TextView)的示例,實際的顯示效果是在整個UI界面的左上方打印一段文字“I am a TextView”。

代碼清單 2-17

<TextView android:id="@+id/text"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:text="I am a TextView" />

Android UI控件使用android:layout_width和android:layout_height屬性控制其寬度和高度,屬性值為wrap_content表示元素的外觀由內容大小決定,而fill_parent則表示元素大小由外層的元素決定。我們經常使用fill_parent來實現自適應的界面布局,因為最外層的元素必然就是手機屏幕。此外我們需要注意的是,這兩個屬性是每個UI控件必須指定的。

另外,Android UI控件的外觀采用類似于CSS標準的“盒子模型”,也有margin和padding的概念,元素內邊距使用android:padding來表示,外邊距則采用android:layout_margin來控制。這兩個屬性也是我們最常使用的“利器”之一,用其可使整個界面各個控件之間的間隔更為合理、美觀。Android UI控件“盒子模型”如圖2-7所示,大家可以結合示意圖理解一下。

圖2-7 盒子模型

最后,我們來學習一些基礎的Android UI控件屬性,這些屬性在UI組件基礎類View類中定義,具備很強的通用性,可被絕大部分的UI控件所使用,因此也被稱作“通用屬性”。對于我們來說,只有掌握了這些通用屬性的用法,才能夠更好地控制UI組件并運用它們組裝出各種各樣的UI界面。

·android:id:每個UI控件的代表性id。我們經常在程序中使用findViewById方法來選取對應id的控件,然后再對該控件進行屬性控制或者事件處理,用法和HTML元素標簽屬性中的id類似。

·android:background:控件背景,可以是顏色值,也可以是圖像或者Drawable資源等,如果值為@null,則表示透明背景。

·android:layout_width:UI控件的寬度,常見屬性有fill_parent、wrap_parent等。前面我們已經簡單介紹過這個屬性的用法,它是每個控件必須具備的屬性之一。

·android:layout_height:UI控件的高度,常見屬性和用法和寬度一樣,也是每個控件必須具備的屬性之一。

·android:layout_gravity:用于控制UI控件相對于其外層控件的位置,其屬性值就代表其位置,如頂部(top)、底部(bottom)、左邊(left)、右側(right)、垂直居中(center_vertical)、水平居中(center_horizontal)、絕對居中(center)、垂直填滿(fill_vertical)、水平填滿(fill_horizontal)、完全填滿(fill)等。另外,這些屬性可以并列存在,我們常使用“|”符號隔開,如“center_vertical|center_horizontal”表示垂直水平居中。

·android:layout_margin:UI控件的外邊距,使用方式見圖2-7所示的“盒子模型”。

·android:padding:UI控件的內邊距,使用方式見圖2-7所示的“盒子模型”。

·android:gravity:控件內部的元素相對于控件本身的位置,其屬性值和使用方法與android:layout_gravity基本一致。

·android:visibility:顯示或隱藏控件,控件默認是顯示狀態的。

通用屬性常用于操控UI控件的外觀和位置,通常能對UI界面的構建起到很大的作用。當然,除了通用屬性之外,不同的UI控件還會有各自專屬的“控件屬性”,這些屬性我們將在后面講到各種UI控件的概念和用法時詳細介紹,具體內容可參考第7章中與界面控件相關的章節內容。

2.7.2 布局(Layout)

Android UI系統中的布局文件其實和HTML有點類似,都是用XML標簽所代表的各種UI控件組合或者嵌套而成的,只不過,Android模板文件的格式比HTML更嚴謹些,屬性也更復雜些。在Android UI界面設計中,Layout布局控件就像“建筑師”一樣,幫助我們把整個界面的框架布局搭建起來,并把每個控件都放到合適的位置上。我們最經常使用的布局有以下幾種,我們來逐個介紹一下。

1.基本布局(FrameLayout)

基本布局(FrameLayout)是所有Android布局中最基本的,此布局實際上只能算是一個“容器”,里面所有的元素都不能被指定位置,默認會被堆放到此布局的左上角。此布局在普通的應用中用得不是很多,但是因為簡單高效,所以在一些游戲應用中還是經常被用到。

2.線性布局(LinearLayout)

線性布局(LinearLayout)是應用開發中最常用的布局之一,分為橫向和縱向兩種,由android:orientation屬性來控制。當屬性值為“horizontal”時表示橫向的線性布局,常用于并排元素的界面;而“vertical”則表示縱向也就是垂直的線性布局,它的用處更廣,普通應用中的大部分界面都是垂直排列的,比如列表界面、配置界面等。

線性布局的用法很簡單,就拿垂直的線性布局來說,我們只要把所需的控件按照順序放到布局標簽中間就可以了,Android UI系統會自動按照從上到下的順序展示出來。代碼清單2-18就是一個簡單的代碼示例,其功能很簡單,就是把一個TextView和Button垂直并排在這個線性布局中。大家在閱讀示例代碼的同時可以順便復習一下UI控件屬性的用法。

代碼清單 2-18

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

3.相對布局(RelativeLayout)

相對布局(RelativeLayout)也是最常使用的布局之一,由于其內部的所有元素都是按照相對位置來排列的,所以不需要嵌套其他的布局,它可以使UI模板布局更加地簡潔和高效。該布局中的控件元素都是以“參照控件”為準來排布的,比如控件屬性設置為“android:layout_toRightOf="@+id/referBox"”,則表示該控件位于id為referBox的參照控件的右邊。以下是相對布局中其他常用屬性的列表,供大家參考。

·android:layout_toLeftOf:該控件位于參照控件的左方。

·android:layout_toRightOf:該控件位于參照控件的右方。

·android:layout_above:該控件位于參照控件的上方。

·android:layout_below:該控件位于參照控件的下方。

·android:layout_alignParentLeft:該控件是否與父組件的左端對齊。

·android:layout_alignParentRight:該控件是否與父組件的右端對齊。

·android:layout_alignParentTop:該控件是否與父組件的頂部對齊。

·android:layout_alignParentBottom:該控件是否與父組件的底部對齊。

·android:layout_centerInParent:該控件是否與父組件居中對齊。

·android:layout_centerHorizontal:該控件是否與父組件橫向居中對齊。

·android:layout_centerVertical:該控件是否與父組件垂直居中對齊。

4.絕對布局(AbsoluteLayout)

絕對布局(AbsoluteLayout)的用法類似于HTML中的層屬性“position=absolute”,該布局內部的控件可以使用android:layout_x和android:layout_y兩個屬性來指定它相對于布局坐標軸原點的X軸和Y軸方向的距離。圖2-8就是絕對布局的示意圖。

圖2-8 絕對布局的示意圖

5.表格布局(TableLayout)

大家如果熟悉HTML的話,應該非常熟悉表格布局(TableLayout),像一些表格型的信息列表都是使用表格布局來展示的。表格型布局的標簽有兩個——<TableLayout/>和<TableRow/>,前者是表格布局的主要標簽,整個表格布局的框架,類似于HTML標簽中的<table/>;后者是表格行,類似于HTML標簽中的<th/>或者<tr/>。表格布局的使用范例如代碼清單2-19所示。

代碼清單 2-19

<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:stretchColumns="0,1,2">
  <TableRow>
        <TextView android:gravity="center" android:text="ID"/>
        <TextView android:gravity="center" android:text="NAME"/>
  </TableRow>
  <TableRow>
        <TextView android:gravity="center" android:text="1"/>
        <TextView android:gravity="center" android:text="james"/>
        <Button android:layout_width="wrap_content" 
              android:layout_height="wrap_content"
              android:gravity="center" 
              android:text="Edit"/>
  </TableRow>
  <TableRow>
        <TextView android:gravity="center" android:text="2"/>
        <TextView android:gravity="center" android:text="iris"/>
        <Button android:layout_width="wrap_content" 
              android:layout_height="wrap_content"
              android:gravity="center" 
              android:text="Edit"/>
  </TableRow>
</TableLayout>

上述XML模板的最終顯示結果如圖2-9所示,我們可以看到,這是一個3行3列的標準表格結構,對應到代碼中就是3個<TableRow/>標簽,每個標簽中包含3個控件。

圖2-9 表格布局示例

另外,我們還要注意的是,<TableLayout/>有3個很重要的屬性:android:stretchColumns、android:shrinkColumns和android:collapseColumns,分別對應的是拉伸、收縮和隱藏列行為,如代碼清單2-19中我們使用“android:stretchColumns="0,1,2"”,就表示所有列都是拉伸狀態,因此每列中的控件才會平分并填滿整行的空間;假如我們設置“android:collapseColumns="2"”,那么最右邊的列將會被隱藏。

6.標簽布局(TabLayout)

標簽布局(TabLayout)在移動應用中是相當流行的,其用法相對比其他布局復雜一些,需要配合程序來實現。接下來我們來看一個簡單的標簽布局的實例,其模板文件如代碼清單2-20所示。

代碼清單 2-20

<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@android:id/tabhost_id"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
  <LinearLayout android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:padding="5dp">
        <TabWidget android:id="@android:id/tabtitle_id"
              android:layout_width="fill_parent"
              android:layout_height="wrap_content" />
        <FrameLayout android:id="@android:id/tabcontent_id"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent" />
  </LinearLayout>
</TabHost>

此界面最外面是一個<TabHost/>標簽,里面嵌套了一個垂直的線性布局,該線形布局里面又包含了一個<TabWidget/>和<FrameLayout/>,這些標簽都是需要在程序中設置的。緊接著,在模板對應的Activity類中設置該TabLayout的邏輯,使用范例見代碼清單2-21。

代碼清單 2-21

public class TabDemo extends TabActivity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // 初始化資源對象
        Resources res = getResources();
        TabHost tabHost = getTabHost();
        TabHost.TabSpec ts;
        Intent intent;

        // 設置第1Tab
        intent = new Intent().setClass(this, Tab1Activity.class);
        ts = tabHost
              .newTabSpec("tab1")
              .setIndicator("Tab1", res.getDrawable(R.drawable.ic_tab_1))
              .setContent(intent);
        tabHost.addTab(ts);

        // 設置第2Tab
        intent = new Intent().setClass(this, Tab2Activity.class);
        ts = tabHost
              .newTabSpec("tab2")
              .setIndicator("Tab2", res.getDrawable(R.drawable.ic_tab_2))
              .setContent(intent);
        tabHost.addTab(ts);

        // 設置第3Tab
        intent = new Intent().setClass(this, Tab3Activity.class);
        ts = tabHost
              .newTabSpec("tab3")
              .setIndicator("Tab3", res.getDrawable(R.drawable.ic_tab_3))
              .setContent(intent);
        tabHost.addTab(ts);

        // 設置默認選中Tab
        tabHost.setCurrentTab(0);
  }
  ...
}

我們從代碼注釋中可以清楚地看到,在該實例中我們添加了3個Tab標簽,程序使用newTabSpec方法獲取TabHost.TabSpec對象,然后使用setIndicator和setContent方法設置Tab的頂部樣式和內部信息,最后再調用setCurrentTab方法設置默認選中的標簽頁。最后,分別實現Tab1Activity、Tab2Activity和Tab3Activity界面類的邏輯,并加入聲明到Manifest應用的配置文件中。至此,整個標簽布局的設置就完成了。

2.7.3 事件(Event)

了解完UI控件和界面布局的基本知識之后,我們還需要知道如何控制這些界面上的控件元素。Android應用框架為我們提供了事件機制來處理用戶觸發的動作,常見的事件包括鍵盤事件KeyEvent、輸入事件InputEvent、觸屏事件MotionEvent等。在實際應用中,我們需要掌握如何響應當用戶操作這些控件時所觸發的事件。比如,用戶點擊某個按鈕控件(Button)之后需要執行一些程序邏輯,此時我們需要使用Android系統給我們提供的事件監聽器Listener來捕獲按鈕的點擊事件來執行這些邏輯。本節中我們將會介紹Android應用框架中比較常見的監聽器。

1.View.OnClickListener事件

View.OnClickListener是最經常使用的監聽器之一,用于處理點擊事件。其實,該類也是View基類中的公用接口,其接口方法為onClick(View v)。方法只有一個參數,就是點擊事件觸發的控件對象的本身。我們在使用過程中必須實現onClick方法,也就是把點擊之后需要處理的邏輯代碼放到此方法中。代碼清單2-22就是相關的使用范例。

代碼清單 2-22

btnObj = (Button) this.findViewById(R.id.demo_btn_id);
btnObj.setOnClickListener(new OnClickListener() {
   @Override
   public void onClick(View v) {
        // 按鈕點擊之后的動作
        ...
  }
});

上面的代碼實現的就是id為demo_btn_id的按鈕控件的點擊事件,我們在使用findViewById獲取到按鈕實例對象之后,又通過setOnClickListener方法設置View.OnClickListener監聽器對象的實現,點擊事件需要處理的邏輯我們會在onClick方法中實現。大家可以看到,Android UI事件的概念和用法與JavaScript語言有點類似。

2.View.OnFocusChangeListener事件

監聽器View.OnFocusChangeListener用于處理選中事件,比如界面中有若干個UI控件,當需要根據選中不同的控件來處理不同的邏輯時,就可以使用按鈕控件對象的setOnFocusChangeListener方法來設置View.OnClickListener監聽器對象。選中需要處理的邏輯會在該監聽器對象的onFocusChange方法中實現。

onFocusChange方法有兩個參數:第一個是事件觸發的控件對象,我們可以用其判斷并處理不同控件的觸發事件,另一個則是布爾型的值,表示該控件對象的最新狀態。另外,監聽器的具體用法和View.OnClickListener類似。

3.View.OnKeyListener事件

監聽器View.OnKeyListener用于處理鍵盤的按鍵。我們可以在該監聽器的onKey方法中處理用戶點擊不同按鍵時所需要處理的邏輯。在Android的鍵盤系統中,每個按鍵都有自己的代碼,也就是keyCode。需要注意的是,onKey方法的第二個參數傳遞的就是用戶點擊按鍵的keyCode,而后我們就可以使用switch語句來處理不同的按鍵事件了。這個思路其實和JavaScript中的onkey系列方法非常類似,讀者如果熟悉JavaScript的話,可以對照著學習一下。

4.View.OnTouchListener事件

監聽器View.OnTouchListener用于處理Android系統的觸屏事件。如果我們需要對一些觸摸動作做處理,或者需要處理比點擊動作此類動作更細粒度的動作的話,就要用到這個監聽器了。此監聽器必須實現的接口方法是onTouch(View v,MotionEvent event),我們需要注意的是第二個參數,因為這個參數表示的是用戶觸發的動作事件,我們可以根據這個參數的值來處理比較復雜的手勢(gesture)動作。

MotionEvent事件中比較常見的動作和手勢常量的說明如下,供大家參考。

·ACTION_DOWN:按下手勢,包含用戶按下時的位置信息。

·ACTION_UP:松開手勢,包含用戶離開時的位置信息。

·ACTION_MOVE:拖動手勢,包含最新的移動位置。

·ACTION_CANCEL:結束手勢,類似于ACTION_UP,但是不包含任何位置信息。

·ACTION_OUTSIDE:離開控件元素時所觸發的事件,只包含初始的位置信息。

·EDGE_BOTTOM:碰觸屏幕底部時所觸發的事件。

·EDGE_LEFT:碰觸屏幕左邊時所觸發的事件。

·EDGE_RIGHT:碰觸屏幕右邊時所觸發的事件。

·EDGE_TOP:碰觸屏幕頂部時所觸發的事件。

·ACTION_MASK:多點觸碰事件的標志,可用于處理多點觸摸事件。

·ACTION_POINTER_DOWN:第二點按下時的觸發事件。

·ACTION_POINTER_UP:第二點松開時的觸發事件。

可以想象,如果缺少事件響應的支持,Android應用的界面將會變得毫無交互性。因此,學會使用UI控件的各種響應事件的用法對于Android應用開發來說是非常重要的。通常情況下,我們會使用不同的事件來讓界面中的元素生動起來。比如,我們可以通過實現某個UI控件的View.OnClickListener事件來響應用戶的點擊動作(如代碼清單2-22所示),或者還可以使用View.OnTouchListener事件來響應一些更加復雜的動作。

2.7.4 菜單(Menu)

菜單是Android應用系統中最有特色的功能之一,也是每個Android應用必不可少的組件之一。合理地使用菜單不僅可以幫助我們節省界面空間,還可以提升用戶的操作體驗。一般,我們最常用的菜單有以下3種,下面我們分別來學習一下。

1.選項菜單(Options Menu)

選項菜單(Options Menu)是Android應用中最經常被使用的菜單,當用戶按下系統菜單鍵時出現。在Activity中,我們通常使用onCreateOptionsMenu方法來初始化菜單項,然后再使用onOptionsItemSelected方法處理每個菜單項選中時的邏輯。使用范例如代碼清單2-23所示。

代碼清單 2-23

public class MenuActivity extends Activity {

  ...
  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        // 添加書寫按鈕菜單項
        menu.add(0, MENU_APP_WRITE, 0, R.string.menu_app_write).setIcon(...);
        // 添加注銷按鈕菜單項
        menu.add(0, MENU_APP_LOGOUT, 0, R.string.menu_app_logout).setIcon(...);
        return true;
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
              case MENU_APP_WRITE:
                    // 點擊書寫菜單項之后的邏輯
                    ...
                    break;
              case MENU_APP_LOGOUT:
                    // 點擊注銷菜單項之后的邏輯
                    ...
                    break;
        }
        return super.onOptionsItemSelected(item);
  }
}

當然,如果我們需要添加一些每次菜單加載時都需要執行的邏輯,則需要使用onPrepareOptionsMenu方法來處理,因為onCreateOptionsMenu只在菜單項初始化的時候執行一次。

2.上下文菜單(Context Menu)

上下文菜單(Context Menu)的概念和PC上應用軟件的快捷菜單有點類似,在UI控件注冊了此菜單對象以后,長按視圖控件(2秒以上)就可以喚醒上下文菜單。在Activity類中,我們可以使用onCreateContextMenu方法來初始化上下文菜單。和選項菜單略微不同的是,此方法在每次菜單展示的時候都會被調用。另外,處理上下文菜單點擊事件的方法名為onContextItemSelected,其用法和前面介紹的選項菜單中的onOptionsItemSelected方法類似。

3.子菜單(Submenu)

在Android應用中點擊子菜單時會彈出懸浮窗口顯示子菜單項,子菜單(Submenu)可以被添加到其他的菜單中去。使用方法也很簡單,Submenu的使用范例如代碼清單2-24所示。我們需要注意的是,子菜單是不可以嵌套的,即子菜單中不能再包含其他子菜單,我們在使用的時候必須注意這個問題。

代碼清單 2-24

publicboolean onCreateOptionsMenu(Menu menu) {
  // 初始化變量
  int base = Menu.FIRST;

  // 添加子菜單
  SubMenu subMenu = menu.addSubMenu(base, base+1, Menu.NONE, "子菜單-1");
  // 設置圖標
  subMenu.setIcon(R.drawable.settings);

  // 添加子菜單項
  subMenu.add(base, base+1, base+1, "子菜單項-1");
  subMenu.add(base, base+2, base+2, "子菜單項-2");
  subMenu.add(base, base+3, base+3, "子菜單項-3");
  return true;
}

以上我們介紹了Android系統中最常見的幾種菜單的概念和基本用法,關于菜單組件實際運用的更多信息,我們將在實戰篇的7.5.1節中結合實際案例做進一步的介紹。

2.7.5 主題(Theme)

為了讓Android UI界面開發更加快速方便,同時具有更好的復用性,應用框架為我們提供了樣式(style)和主題(theme)兩個功能。這兩個功能讓我們可以更好地控制UI界面的外觀,并可以實現一些更高級的功能,比如換膚功能等。

首先,需要了解的是,我們通常會把樣式和主題的聲明放在Android應用框架的資源目錄res/values/下的styles.xml文件中,使用范例如代碼清單2-25所示。

代碼清單 2-25

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <style name="CommonText" parent="@style/Text">
    <item name="android:textSize">12px</item>
    <item name="android:textColor">#008</item>
  </style>
</resources>

我們可以看到,在這個樣式文件中我們聲明了一個名為“CommonText”的樣式,里面包含了該樣式的兩個屬性:字體大小“android:textSize”和字體顏色“android:textColor”屬性。另外,樣式是支持繼承的,比如,該樣式就繼承自系統的基礎“Text”樣式,這種使用parent屬性設置父樣式的用法還是比較容易理解的。了解完樣式和主題的寫法,接下來讓我們認識一下樣式和主題之間的區別。

1.樣式(style)

Android的UI系統中,樣式(style)的概念和CSS中樣式的概念非常類似,我們可以把一些常用的樣式提取出來,比如代碼清單2-20中,我們就把一種常見的文字樣式提取出來并保存為“CommonText”的樣式。應用樣式的時候,我們只需要在對應控件的聲明中加上“style="@style/CommonText"”屬性值即可。一般來說,樣式都只會被應用于單個View控件中。

2.主題(theme)

與樣式不同,主題(theme)一般被用于更外層的ViewGroup控件中,比如,我們需要讓Activity下所有控件的字體都用CommonText的樣式,那么我們就可以在應用配置文件中的<activity/>標簽加上“android:theme="CommonText"”的屬性。但是,如果我們把樣式用在ViewGroup上,對于ViewGroup之下的其他View控件卻是沒有影響的。另外,Android系統還定義了幾個基本的系統主題供我們使用,比如Theme.Light主題就是以亮色背景為基調的主題樣式。

學會靈活使用樣式和主題來渲染Android應用的UI界面是非常重要的,因為該技術不僅可以讓界面設計更加容易,還可以簡化模板文件的代碼,減少開發成本。因此,在實踐的過程中,我們要有意識地去運用這些知識和技巧,逐漸掌握Android UI系統的使用。

2.7.6 對話框(Dialog)

在Android應用界面中,經常需要彈出一些懸浮于底層UI界面之上的操作窗口。當這種窗口顯示的時候,底層界面通常會被半透明層所覆蓋住,焦點則會被該窗口獲得,這種窗口就被稱為對話框,或者是Dialog。應用中常用的Dialog有提示對話框(AlertDialog)、進度對話框(ProgressDialog)、日期選擇對話框(DatePickerDialog)以及時間選擇對話框(TimePickerDialog)等。在本節中,我們將重點介紹其中較常使用的兩種Dialog的用法。

1.提示對話框(AlertDialog)

提示對話框(AlertDialog)可以算是Android應用中最經常使用的對話框控件了,其主要用于顯示提示信息,當然,可以加上確認和取消(YES和NO)按鈕。創建AlertDialog需要使用AlertDialog.Builder子類,代碼清單2-26演示了創建AlertDialog對話框的標準過程。

代碼清單 2-26

AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Are you sure you want to exit?")
  .setCancelable(false)
  .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int id) {
              MyActivity.this.finish();
        }
  })
  .setNegativeButton("No", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int id) {
              dialog.cancel();
        }
  });
AlertDialog alert = builder.create();
alert.show();

在以上代碼中,首先使用AlertDialog.Builder(Context)方法來獲取Builder對象,然后使用Builder類提供的公用方法來設置AlertDialog的文字和屬性,接著使用該類的create方法來創建AlertDialog對象,最后調用show方法展示該對話框。顯示效果如圖2-10所示。

圖2-10 提示對話框示例

2.進度對話框(ProgressDialog)

進度對話框(ProgressDialog)在Android應用開發中也經常會用到,主要用于在耗時操作等待時顯示。其用法比較簡單,一般情況下,只需要調用ProgressDialog的show方法即可,如代碼清單2-27所示。

代碼清單 2-27

...
ProgressDialog dialog = ProgressDialog.show(this, "", "Loading. Please wait...", true);
...

以上代碼創建了一個最基本的進度對話框,顯示效果如圖2-11所示。

圖2-11 進度對話框示例

當然,ProgressDialog類還提供了豐富的對話框屬性設置方法,如設置進度條的樣式、標題、提示信息,以及是否顯示按鈕等。更多用法示例可參考后面7.11.3節中的內容。至于其他對話框的用法由于篇幅原因,這里不做詳細介紹。

主站蜘蛛池模板: 那坡县| 莆田市| 敦煌市| 南川市| 涡阳县| 霍林郭勒市| 基隆市| 永春县| 青冈县| 莆田市| 彭州市| 丰城市| 陇南市| 永吉县| 穆棱市| 赣榆县| 南澳县| 红安县| 汝城县| 北流市| 莱芜市| 朝阳市| 商都县| 鹰潭市| 永嘉县| 太和县| 浮梁县| 汤原县| 贵定县| 岳阳县| 民权县| 安达市| 灵丘县| 和平县| 宿迁市| 刚察县| 和林格尔县| 天气| 剑川县| 光山县| 邛崃市|