Download presentation
Presentation is loading. Please wait.
Published bySiska Salim Modified 5年之前
1
第8章 對話方塊與資源管理 8-1 對話方塊的基礎 8-2 建立與顯示對話方塊 8-3 使用DialogFragment建立對話方塊
8-4 資源管理 8-5 使用Android資源
2
8-1 對話方塊的基礎-種類 Android的對話方塊就是Dialog類別和其子類別,其類別架構如下圖所示:
3
8-1 對話方塊的基礎-Dialog類別 在AlertDialog類別的三個子類別可以建立特殊用途的對話方塊,其說明如下表所示:
ProgressDialog 顯示執行進度的對話方塊 DatePickerDialog 設定日期對話方塊,其內容就是DatePicker元件,可以幫助我們設定日期 TimePickerDialog 設定時間對話方塊,其內容就是TimePicker元件,可以幫助我們設定時間
4
8-1 對話方塊的基礎-生命周期 Android對話方塊的生命周期就是第7-5節Fragment片段的生命周期,我們在第8-3節建立的對話方塊是一種特殊版本的Fragment片段,直接使用Fragment片段的生命周期來管理對話方塊。 換句話說,當Android活動需要管理和重複使用多個對話方塊時,就是使用第8-3節的DialogFragment類別來建立對話方塊。
5
8-2 建立與顯示對話方塊 8-2-1 訊息對話方塊 8-2-2 確認對話方塊 8-2-3 單選對話方塊 8-2-4 複選對話方塊
6
8-2-1 訊息對話方塊 – 說明 在活動建立對話方塊最簡單的方法是透過AlertDialog.Builder類別來建立與顯示警告對話方塊(AlertDialog),這是一個簡單的彈出式視窗來取得使用者的回應。 訊息對話方塊就是顯示一段訊息,例如:在Android應用程式建立「關於」對話方塊。
7
8-2-1 訊息對話方塊 – AlertDialog類別
AlertDialog類別提供內建的對話方塊元素,我們可以直接建立AlertDialog.Builder物件來建立AlertDialog對話方塊,如下所示: AlertDialog.Builder builder = new AlertDialog.Builder(this); 程式碼的建構子參數是Context物件,我們可以使用this取得活動的Context物件,然後使用相關方法來指定對話方塊的內容,如下所示: builder.setTitle("關於"); builder.setMessage("版本: 7.0版\n作者: 陳會安");
8
8-2-1 訊息對話方塊 – 新增按鈕與事件處理 AlertDialog.Builder物件只需使用上表最後三個方法,就可以在對話方塊建立「確定」、「放棄」和「取消」按鈕,以確定按鈕為例,如下所示: builder.setPositiveButton("確定", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialoginterface, int i) { // 不作任何事 } });
9
8-2-2 確認對話方塊 – 說明 一般來說,確認對話方塊至少有兩個按鈕,一個是確認;另一個是取消,例如:建立離開Android應用程式時的確認對話方塊。
10
8-2-2 確認對話方塊 – 建立 確認對話方塊至少有兩個按鈕,我們需要在訊息對話方塊新增一個「取消」按鈕,而且是使用串流呼叫來建立確認對話方塊,如下所示: builder.setTitle("確認") .setMessage("確認結束本程式?") .setPositiveButton("確定", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialoginterface, int i) { finish(); } }) .setNegativeButton("取消", null) .show();
11
8-2-3 單選對話方塊 – 說明 AlertDialog類別也可以用來建立選擇功能的對話方塊,在這一節是單選,下一節說明複選的對話方塊。
在本節範例的AlertDialog物件是在onCreate()方法建立,而且Button元件註冊的是具名傾聽者物件,其事件處理方法只是單純顯示建立的對話方塊。
12
8-2-3 單選對話方塊 – 建立單選對話方塊 單選AlertDialog對話方塊是使用setItems()方法來指定選項,每一個選項可以視為是一個按鈕,如下所示: String[] options = {"紅色", "黃色", "綠色" }; builder.setItems(options, listener); builder.setNegativeButton("取消", null); dialog = builder.create(); dialog.show();
13
8-2-3 單選對話方塊 – 判斷使用者的選擇 單選對話方塊的每一個選項都可以視同是一個按鈕,所以listener傾聽者物件一樣是實作DialogInterface.OnClickListener,如下所示: DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { Button btn = (Button) findViewById(R.id.button1); switch(which){ case 0: btn.setBackgroundColor(Color.RED); break; ….. } };
14
8-2-4 複選對話方塊 – 說明 AlertDialog類別也可以用來建立複選對話方塊,我們是在onCreate()方法建立AlertDialog物件。 在Android應用程式建立複選對話方塊,可以選擇曾使用過的智慧型手機作業系統,請按【複選選項】鈕顯示複選對話方塊,其執行結果如右圖所示:
15
8-2-4 複選對話方塊 – 建立複選對話方塊 AlertDialog.Builder建立複選對話方塊是使用setMultiChoiceItems()方法,如下所示: String[] items = {"Samsung", "HTC", "Apple", "ASUS"}; boolean[] itemsChecked = new boolean[items.length]; …… .setMultiChoiceItems(items,itemsChecked, new DialogInterface.OnMultiChoiceClickListener() { public void onClick(DialogInterface dialog, int which, boolean isChecked) { Toast.makeText(MainActivity.this, items[which] + (isChecked ? " 勾選": "沒有勾選"), Toast.LENGTH_SHORT).show(); } })
16
8-2-4 複選對話方塊 – 取得使用者的選擇 當使用者在對話方塊勾選選項後,按【確定】鈕,就可以在此按鈕的onClick()方法取得使用者的選擇,如下所示: public void onClick(DialogInterface dialoginterface, int i) { String msg = ""; for (int index = 0; index < items.length; index++) { if (itemsChecked[index]) msg += items[index] + "\n"; } TextView output = (TextView) findViewById(R.id.lblOutput); output.setText(msg);
17
8-3 使用DialogFragment建立對話方塊
8-3-1 使用AlertDialog.Builder類別 8-3-2 使用Fragment建立對話方塊 8-3-3 顯示執行進度對話方塊 8-3-4 設定日期或時間
18
8-3-1 使用AlertDialog.Builder類別 – 說明
DialogFragment屬於Fragment子類別,可以建立和顯示位在活動介面上方的對話方塊。 基本上,DialogFragment本身就包含Dialog物件,我們可以使用Fragment片段的版面配置來建立對話方塊,也可以使用AlertDialog.Builder類別來建立對話方塊。
19
8-3-1 使用AlertDialog.Builder類別 – DialogFragment類別宣告 1
public Dialog onCreateDialog(Bundle savedInstanceState) { String title = getArguments().getString("title"); AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); return builder.setTitle(title) .setMessage("確認結束本程式?") .setPositiveButton("確定", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialoginterface, int whichButton) { ((MainActivity) getActivity()).doPositiveClick(); } })
20
8-3-1 使用AlertDialog.Builder類別 – DialogFragment類別宣告 2
.setNegativeButton("取消", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { ((MainActivity) getActivity()).doNegativeClick(); } }) .create();
21
8-3-2 使用Fragment建立對話方塊 – 說明
如同第7-5節的Fragment片段,我們可以使用片段的版面配置來建立自訂對話方塊的使用介面。請參閱第7-5-2節使用Android Studio範本新增Fragment片段後,再修改成本節DialogFragment對話方塊。 請注意!DialogFragment就是一種Fragment片段,只是顯示外觀是對話方塊,其實作和建立Fragment片段並沒有什麼不同,這部分筆者就不重複說明。
22
8-3-2 使用Fragment建立對話方塊 – 範例
本節範例類似第7-5-3節前半段,我們需要將DialogFragment片段輸入的姓名字串傳遞至MainActivity活動來顯示,使用的是Fragment和活動之間的資料傳遞,詳細說明請參閱第7-5-3節。
23
8-3-3 顯示執行進度對話方塊 – 說明 在DialogFragment類別可以使用「執行進度對話方塊」(ProgessDialog)來顯示操作進度,例如:下載檔案的進度。
24
8-3-3 顯示執行進度對話方塊 – 建立ProgressDialog對話方塊1
在DialogFragment類別建立執行進度對話方塊,就是建立ProgressDialog物件,如下所示: private ProgressDialog pDialog; ...... public Dialog onCreateDialog(Bundle savedInstanceState) { String title = getArguments().getString("title"); pDialog = new ProgressDialog(getActivity()); pDialog.setTitle(title); pDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); pDialog.setProgress(0);
25
8-3-3 顯示執行進度對話方塊 – 建立ProgressDialog對話方塊2
ProgressDialog對話方塊是使用setButton()方法建立按鈕,如下所示: pDialog.setButton(DialogInterface.BUTTON_POSITIVE, "隱藏" , new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { ((MainActivity) getActivity()).doPositiveClick(); } });
26
8-3-3 顯示執行進度對話方塊 – 建立ProgressDialog對話方塊3
pDialog.setButton(DialogInterface.BUTTON_NEGATIVE, "取消" , new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { ((MainActivity) getActivity()).doNegativeClick(); } }); return pDialog;
27
8-3-3 顯示執行進度對話方塊 – 顯示執行進度的狀態1
在對話方塊顯示執行進度的狀態需要使用在背景執行的執行緒,我們是在MainActivity活動使用Handler物件(屬於android.os套件)來排程送出訊息,以便定時更新目前進度。在button_Click()方法顯示對話方塊後,重設進度和送出訊息,如下所示: p = 0; // 重設 pHandler.sendEmptyMessage(0); 上述變數p是計數器從0~100,初值是0,呼叫Handler物件的sendEmptyMessage()方法送出參數整數值的訊息,可以指定目前進度為0。
28
8-3-3 顯示執行進度對話方塊 – 顯示執行進度的狀態2
送出的訊息是讓Handler物件指定的回撥方法來處理,如下所示: pHandler = new Handler() { public void handleMessage(Message msg) { super.handleMessage(msg); // 處理訊息 } }; 上述程式碼建立Handler物件,建構子參數是handlerMessage()回撥方法,可以處理Handler物件送出的訊息,第1行呼叫父類別的同名方法。
29
8-3-3 顯示執行進度對話方塊 – 顯示執行進度的狀態3
然後是處理訊息的if/else條件敘述,如下所示: if ( p >= 100 ) { dlg.dismiss(); TextView output = (TextView) findViewById(R.id.lblOutput); output.setText("下載已完成...."); } else { p++; dlg.updateProgress(); // 更新進度 pHandler.sendEmptyMessageDelayed(0,50); }
30
8-3-3 顯示執行進度對話方塊 – 顯示執行進度的狀態4
如果變數p超過100,就呼叫dismiss()方法移除對話方塊後,在TextView元件顯示下載完成的訊息文字。上述updateProgress()方法是位在ProgressDialogFragment類別,呼叫incrementProgressBy()方法來更新進度,參數就是增加值,如下所示: public void updateProgress() { pDialog.incrementProgressBy(1); }
31
8-3-4 設定日期或時間 – 說明 在DialogFragment類別可以建立設定日期或時間的對話方塊,就是分別使用DatePickerDialog和TimePickerDialog類別來建立對話方塊。
32
8-3-4 設定日期或時間 – DatePickerDialog類別1
DatePickerDialog dDialog; dDialog = new DatePickerDialog(getActivity(), listener,year,month,day); 上述建構子的第1個參數是Context物件,第2個是傾聽者物件,第3~5個是初始的年、月和日。我們可以使用Calendar物件dt來指定初值,如下所示: dt.get(Calendar.YEAR) dt.get(Calendar.MONTH) dt.get(Calendar.DAY_OF_MONTH) 上述程式碼使用get()方法依序取出年、月和日。
33
8-3-4 設定日期或時間 – DatePickerDialog類別2
傾聽者物件listener是DatePickerDialog.OnDateSetListener介面的物件,需要實作onDateSet()方法,如下所示: public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { …... } 上述方法的參數year、monthOfYear和dayOfMonth,就是選擇的年、月和日。
34
8-3-4 設定日期或時間 – TimePickerDialog類別1
TimePickerDialog tDialog; tDialog = new TimePickerDialog(getActivity(), listener,hour,minute, is24HourView); 上述建構子的第1個參數是Context物件,第2個是傾聽者物件,第3~4個是初始的時和分。我們可以使用Calendar物件dt來指定初值的時和分,如下所示: dt.get(Calendar.HOUR) dt.get(Calendar.MINUTE) 第5個參數是24小時制,true為24小時。
35
8-3-4 設定日期或時間 – TimePickerDialog類別2
傾聽者物件listener是TimePickerDialog.OnTimeSetListener介面的物件,需要實作onTimeSet()方法,如下所示: public void onTimeSet(TimePicker view, int hourOfDay, int minute) { …… } 上述方法的參數hourOfDay和minute,就是選擇的時和分。
36
8-4 資源管理 – 說明 Android應用程式需要依賴字串、圖形、版面配置和其他資源來建立使用介面,在Android Studio專案就包含這些資源。基本上,資源可以分為兩種,如下所示: 應用程式資源(Application Resources):這些是開發者針對應用程式建立的資源,一些Android Studio專案檔案的專案資源。 系統資源(System Resources):Android作業系統平台定義的資源,可以讓所有Android應用程式透過Android SDK來取得。
37
8-4 資源管理 – 資源種類 Android定義的資源種類(Resources Types)非常多,常用資源種類說明,如下表所示:
資源名稱 說明 目錄 類別 補間動畫 定義補間動畫效果 anim R.anim 色彩 定義介面元件套用的色彩資源 color R.color 尺寸 定義介面元件使用的自訂尺寸 values R.dimen 圖形 定義圖形檔案資源 drawable R.drawable 版面配置 定義使用介面的版面配置 layout R.layout 選單 定義選單內容的選項 menu R.menu 字串 定義字串和字串陣列 R.string、R.array 樣式 定義介面元件套用的樣式 R.style
38
8-4 資源管理 – 資源檔案命名規則 Android應用程式的資源是儲存在「\res\」的子目錄,儲存在此的檔案需要導守的命名規則,如下所示: 資源檔案名稱必須是小寫。 資源檔案名稱只能是英文字母、數字、「_」底線和「.」。 資源檔案名稱必須是唯一。
39
8-4 資源管理 – 在Android Studio建立資源檔案
在Android Studio專案「Project」視窗的【app\res】上,執行【右】鍵快顯功能表的「New/Android resource file」指令新增資源檔,可以看到「New Resource File」對話方塊。
40
8-4 資源管理 – 色彩資源(Color Resources)1
對於Android應用程式介面元件的常用色彩,我們可以建立位在「\res\values」目錄下的色彩資源XML檔,例如:colors.xml,如下所示: <?xml version="1.0" encoding="utf-8"?> <resources> <color name="colorPrimary">#3F51B5</color> <color name="colorPrimaryDark">#303F9F</color> <color name="colorAccent">#FF4081</color> <color name="background_color">#800F</color> <color name="text_color">#FF00FF</color> </resources>
41
8-4 資源管理 – 色彩資源(Color Resources)2
resources根元素下是使用color子元素定義色彩資源(前3個是Material Design的預設色彩),色彩值是12/24位元的RGB值,我們可以在網址: <TextView …... android:text="色彩資源定義的字型色彩"/>
42
8-4 資源管理 – 色彩資源(Color Resources)3
Andorid 6.0以上版本的getColor()方法參數有2個(舊版只有1個參數),新增第2個參數Theme佈景資源,例如:取得background_color資源的背景色彩,如下所示: int bgcolor; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { bgcolor = getResources().getColor( R.color.background_color, getTheme()); } else { R.color.background_color); }
43
8-4 資源管理 – 尺寸資源(Dimension Resources)1
對於介面元件的常用尺寸,我們可以建立位在「\res\values」目錄下的尺寸資源XML檔,例如:dimens.xml,如下所示: <resources> <!-- Default screen margins, per the Android Design guidelines. --> <dimen name="activity_horizontal_margin">16dp</dimen> <dimen name="activity_vertical_margin">16dp</dimen> <dimen name="thumb_dimen">120px</dimen> <dimen name="small_size">10sp</dimen> </resources> 上述resources根元素下使用dimen子元素定義尺寸資源(前2個是預設的螢幕間距),其值就是第6-1-3節Android支援的尺寸單位。
44
8-4 資源管理 – 尺寸資源(Dimension Resources)2
<TextView …... android:text="尺寸資源定義的字型尺寸"/> Java程式碼是使用getDimension()方法取得尺寸資源,例如:thumb_dimen,如下所示: float thumb_size = getResources().getDimension( R.dimen.thumb_dimen);
45
8-4 資源管理 – 字串資源(String Resources)
字串資源是定義Android應用程式顯示的字串,或字串陣列,它是位在「\res\values」目錄下的字串資源XML檔,例如:strings.xml,如下所示: <?xml version="1.0" encoding="utf-8"?> <resources> <string name="height">身高</string> <string name="weight">體重</string> </resources> 在Java程式碼是使用getString()方法取得字串資源,例如:height,如下所示: String height = getResources().getString(R.string.height);
46
8-4 資源管理 – 格式化字串資源(Formatting String Resources)
我們可以使用字串資源如同格式化字串,也就是說在字串之中擁有變數,可以動態由程式碼來指定其值,例如:顯示得分,如下所示: <string name="resultMsg">你的得分為: %1$d 分</string> 上述標籤值中的「%1$d」是變數,第1個變數是%1,第2個是%2,以此類推,之後的$d是變數類型,以此例是數字;$s是字串。在Java程式碼可以指定變數值,如下所示: int score = 20; String resultMsgFmt = getResources().getString(R.string.resultMsg); String resultMsg = String.format(resultMsgFmt, score);
47
8-4 資源管理 – 圖形資源(Drawable Resources)1
圖形資源是在Android應用程式顯示的圖示、圖形和圖形按鈕等點陣圖資源,例如:PNG、JPG和GIF等格式的圖檔。因為行動裝置的螢幕解析度有多種,所以Android SDK定義多種螢幕解析度,如下所示: 低解析度(Low,ldpl):120dpi。 中解析度(Medium,mdpl):160dpi。 高解析度(High,hdpl):240dpi。 超高解析度(Extra High,xhdpl):320dpi。 超超高解析度(Extra Extra High,xxhdpl):480dpi。 超超超高解析度(Extra Extra Extra High,xxhdpl):640dpi。
48
8-4 資源管理 – 圖形資源(Drawable Resources)2
Java程式碼是使用getDrawable()方法取得圖形資源的BitmapDrawable物件,例如:logo.png,如下所示: BitmapDrawable logo = (BitmapDrawable) getResources().getDrawable(R.drawable.logo); 請注意!目前Android Studio專案的應用程式圖示(Icons)並不是位在「drawable」目錄;而是位在「mipmap」目錄,如下圖所示:
49
8-4 資源管理 – 圖形資源(Drawable Resources)3
因為圖形資源的解析度大多不會剛好和裝置螢幕相同,所以系統需要縮放處理圖形,位在「mipmap」目錄的圖形可以最佳化圖形在不同螢幕尺寸的縮放顯示,特別是在需要顯示動畫時。 基本上,「mipmap」目錄的用法和「drawable」目錄並沒有什麼不同,其資源索引是R.mipmap,例如:官方推薦將圖示置於「mipmap」目錄,因為當圖示解析度和螢幕解析度不同時,系統可以自動提供最佳化縮放處理,達到更佳的螢幕顯示和佔用較少的記憶體空間。
50
8-4 資源管理 – 版面配置資源(Layout Resources)
版面配置資源是用來定義活動或元件的使用介面架構,因為第5章已經說明過各種相關XML標籤的使用,所以,筆者準備說明如何建立支援多種螢幕尺寸和橫向螢幕的版面配置。 一般來說,Android作業系統預設自動依照螢幕尺寸來調整版面配置的大小,而且大部分情況,使用預設調整功能即可,除非使用介面在不同螢幕尺寸顯示時仍然有些問題,才需要自行調整。 Android Studio在2.2.x版提供ConstraintLayout版面配置,可以幫助我們建立針對不同螢幕尺寸的版面配置,進一步說明請參閱第5-4節。
51
8-5 使用Android資源 8-5-1 使用應用程式資源 8-5-2 使用Android平台的系統資源
52
8-5-1 使用應用程式資源 – 說明 在Android Studio專案取得應用程式資源有兩種方式,一是在XML檔案使用;一是使用Java程式碼來使用資源。基本上,取得應用程式資源的語法,筆者整理如下表所示: Android資源 在XML檔案參考 使用Java程式碼 res\layout\activity_main.xml @layout/activity_main R.layout.activity_main res\drawable-hdpi\my.png @drawable/my R.drawable.my <string name="go"> @string/go R.string.go @+id/button @id/button R.id.button
53
8-5-1 使用應用程式資源 – 在XML檔案取得應用程式資源(語法)
@[套件名稱:]資源種類/資源名稱 上述語法的說明,如下所示: 套件名稱:資源所在的套件名稱,如果同一個套件就不需指明,例如:系統資源是android:。 資源種類:R類別的子類別名稱,例如:字串資源是string。 資源名稱:沒有副檔名的資源檔名稱,或XML標籤的name屬性值。
54
8-5-1 使用應用程式資源 – 在XML檔案取得應用程式資源(範例1)
例如:在activity_main.xml定義的Button元素,如下所示: <Button android:layout_width="match_parent" android:layout_height="wrap_content" /> 上述android:text屬性值因為是取得同一套件的資源,所以沒有套件名稱,只有資源種類string,它是位在「\res\values\」目錄strings.xml(檔案名稱可自訂。
55
8-5-1 使用應用程式資源 – 在XML檔案取得應用程式資源(範例2)
例如:colors.xml、stuff.xml等)的字串資源,如下所示: <?xml version="1.0" encoding="utf-8"?> <resources> <string name="send">送出</string> </resources> 上述resource根元素代表資源檔,string元素定義同名的字串種類資源,name屬性值就是資源名稱send。
56
8-5-1 使用應用程式資源 – 使用Java程式碼取得應用程式資源
在Java程式碼取得應用程式資源是使用R.java類別的常數,例如:指定活動使用的版面配置資源,如下所示: setContentView(R.layout.activity_main); 上述方法參數R.layout.activity_main是「\res\layout」目錄的activity_main.xml。另一個範例是找出指定的介面元件,如下所示: Button button = (Button) findViewById(R.id.button);
57
8-5-2 使用Android平台的系統資源 Android平台本身就擁有一些預建圖形、音效、字串、動畫、版面配置、色彩和其他種類資源,在XML檔案取得系統資源需要加上【android:】套件名稱,如下所示: @android:drawable/ic_menu_preferences @android:color/holo_blue_bright @android:string/cut 在Java程式碼取得系統資源,請使用【android.R】類別取代【R】類別,如下所示: android.R.strings.yes android.R.strings.no android.R.strings.cancel android.R.strings.ok
58
End
Similar presentations