一、非自定義Dialog的幾種形式介紹
轉自:http://www.kwstu.com/ArticleView/kwstu_20139682354515
前言
對話框對於應用也是必不可少的一個組件,在Android中也不例外,對話框對於一些提示重要信息,或者一些需要用戶額外交互的一些內容很有幫 助。本篇博客就講解一下Android下對話框的使用,在本篇博客中,將了解到對話框的一些常規屬性的設置,以及各式的對話框的使用,並都會提供小 Demo來展示所有的效果。
Dialog
Dialog,對話框,一個對話框就是一個小窗口,並不會填滿整個屏幕,通常是以模態顯示,要求用戶必須采取行動才能繼續進行剩下的操作。
Android提供了豐富的對話框支持,它提供了如下4中常用的對話框:
- AlertDialog:警告對話框,使用最廣泛功能最豐富的一個對話框。
- ProgressDialog:進度條對話框,只是對進度條進行了簡單的封裝。
- DatePickerDialog:日期對話框。
- TimePickerDialog:時間對話框。
所有的對話框,都是直接或間接繼承自Dialog類,而AlterDialog直接繼承自Dialog,其他的幾個類均繼承自AlterDialog。
AlertDialog
AlertDialog繼承自Dialog類,對於Android內置的AlterDialog,它可以包含一個標題、一個內容消息或者一個選擇列表、最多三個按鈕。而 1、創建AlterDialog推薦使用它的一個內部類AlterDialog.Builder創 建。使用Builder對象,可以 2、設置AlterDialog的各種屬性,最后通過 3、Builder.create()就可以得到AlterDialog對 象,如果只是還需要顯示這個AlterDialog,一般可以直接使用 4、Builder.show()方法,它會返回一個AlterDialog對象,並且 顯示它。
如果僅僅是需要提示一段信息給用戶,那么就可以直接使用AlterDialog的一些屬性設置提示信息,涉及到的方法有:
- AlterDialog create():根據設置的屬性,創建一個AlterDialog。
- AlterDialog show():根據設置的屬性,創建一個AlterDialog,並且顯示在屏幕上。
- AlterDialog.Builder setTitle():設置標題。
- AlterDialog.Builder setIcon():設置標題的圖標。
- AlterDialog.Builder setMessage():設置標題的內容。
- AlterDialog.Builder setCancelable():設置是否模態,一般設置為false,表示模態,要求用戶必須采取行動才能繼續進行剩下的操作。
Tips:AlterDialog.Builder的很多設置屬性的方法,返回的均是這個AlterDialog.Builder對象,所以可以使用鏈式方式編寫代碼,這樣更方便。
當一個對話框調用了show()方法后,展示到屏幕上,如果需要消除它,可以使用DialogInterface接口聲明的兩個方 法,cancel()和dismiss()使對話框取或者消除,這兩個方法的作用是一樣的,不過推薦使用dismiss()。Dialog和 AlterDialog都實現了DialogInterface接口,所以只要是對話框,均可以使用這兩個方法來消除對話框。
下面通過一個簡單的Demo,先看看AlterDialog是如何提示信息的:
示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
btnGeneral.setOnClickListener(
new
View.OnClickListener() {
@Override
public
void
onClick(View v) {
// TODO Auto-generated method stub
AlertDialog.Builder builder =
new
AlertDialog.Builder(
MainActivity.
this
);
builder.setTitle(
"提示"
);
builder.setMessage(
"這是一個普通的對話框!"
);
builder.setIcon(R.drawable.ic_launcher);
builder.setCancelable(
false
);
builder.setPositiveButton(
"知道了!"
,
new
OnClickListener() {
@Override
public
void
onClick(DialogInterface dialog,
int
which) {
dialog.cancel();
}
});
builder.create().show();
}
});
|
展示效果:
AlterDialog的按鈕
AlterDialog內置了三個按鈕,可以直接使用setXxxButton()方法進行設置,對於一般的對話框,使用三個按鈕基本上也夠用了,下面是這三個方法的簽名:
- AlterDialog.Builder setPositiveButton(CharSquence text , DialogInterFace.OnClickListener):一個積極的按鈕,一般用於“OK”或者“繼續”等操作。
- AlterDialog.Builder setNegativeButton(CharSquence text , DialogInterFace.OnClickListener):一個負面的按鈕,一般用於“取消”操作。
- AlterDialog.Builder setNeutralButton(CharSquence text , DialogInterFace.OnClickListener):一個比較中性的按鈕,一般用於“忽略”、“以后提醒我”等操作。
上面介紹的DialogInterface接口,還提供了一系列的事件響應,這三個按鈕均需要傳遞一個 DialogInterFace.OnClickListener接口對象,實現其點擊事件的觸發,在這個接口中需要實現一個 onClick(DialogInterface dialog,int which),dialog為當前觸發事件的對話框對象接口,可以直接強制轉換為AlterDialog進行操作;which為點擊按鈕的標識符,是一個 整形的數據,對於這三個按鈕而言,每個按鈕使用不同的int類型數據進行標識:Positive(-1)、Negative(-2)、 Neutral(-3)。
而除了專門為按鈕點擊實現的DialogInterFace.OnClickListener事件外,DialogInterface還提供了 一些其他的事件,供Dialog對象響應,這些事件只是對Dialog聲明周期各個狀態的響應,一看就明白了,就不再詳細講解了,下面是這幾個事件的說 明:
- interface DialogInterface.OnCancelListener:當對話框調用cancel()方法的時候觸發。
- interface DialogInterface.OnDismissListener:當對話框調用dismiss()方法的時候觸發。
- interface DialogInterface.OnShowListener:當對話框調用show()方法的時候觸發。
- interface DialogInterface.OnMultiChoiceListener:當對話框使用多選列表,並且選中的時候觸發。
示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
btnButtons.setOnClickListener(
new
View.OnClickListener() {
@Override
public
void
onClick(View v) {
// TODO Auto-generated method stub
AlertDialog.Builder builder =
new
AlertDialog.Builder(
MainActivity.
this
);
builder.setTitle(
"提示"
);
builder.setMessage(
"這是一個多按鈕普通的對話框!"
);
builder.setIcon(R.drawable.ic_launcher);
builder.setPositiveButton(
"確定"
,
new
OnClickListener() {
@Override
public
void
onClick(DialogInterface dialog,
int
which) {
Toast.makeText(MainActivity.
this
,
"確定被點擊"
,
Toast.LENGTH_SHORT).show();
dialog.dismiss();
}
});
builder.setNegativeButton(
"否定"
,
new
OnClickListener() {
@Override
public
void
onClick(DialogInterface dialog,
int
which) {
// TODO Auto-generated method stub
Toast.makeText(MainActivity.
this
,
"否定被點擊"
,
Toast.LENGTH_SHORT).show();
dialog.dismiss();
}
});
builder.setNeutralButton(
"忽略"
,
new
OnClickListener() {
@Override
public
void
onClick(DialogInterface dialog,
int
which) {
// TODO Auto-generated method stub
Toast.makeText(MainActivity.
this
,
"忽略被點擊"
,
Toast.LENGTH_SHORT).show();
dialog.cancel();
}
});
builder.show();
}
});
|
展示效果:
AlterDialog的列表形式
AlterDialog除了展示一些提示信息,還可以展示一種列表的形式,需要使用到 Builder.setItems(CharSequence[] items,DialogInterface.OnClickListener listener)方法進行設置,它需要傳遞一個CharSequenece類型的數組,以綁定列表的數據,它同樣需要傳遞一個 DialogInterface.OnClickListener接口,以響應列表項的點擊,而這個接口中onClick方法的which參數,為當前點 擊觸發項的items中的下標。
示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
btnListView.setOnClickListener(
new
View.OnClickListener() {
@Override
public
void
onClick(View v) {
// TODO Auto-generated method stub
AlertDialog.Builder builder =
new
AlertDialog.Builder(
MainActivity.
this
);
builder.setTitle(
"請選擇城市"
);
//items使用全局的finalCharSequenece數組聲明
builder.setItems(items,
new
OnClickListener() {
@Override
public
void
onClick(DialogInterface dialog,
int
which) {
// TODO Auto-generated method stub
String select_item = items[which].toString();
Toast.makeText(MainActivity.
this
,
"選擇了---》"
+ select_item, Toast.LENGTH_SHORT)
.show();
}
});
builder.show();
}
});
|
AlterDialog的單選列表
AlterDialog還可以使用一種單選的列表樣式,使用 Builder.setSingleChoiceItems(CharSequenece[] items,int checkedItem,DialogInterface.OnClickListener listener),這個方法具有多項重載,主要是為了應對不同的數據源,items為列表項數組,checkedItem為初始選項,listener 為點擊響應事件。有時候並不一定需要選中之后就關閉對話框,可以設置兩個按鈕,用於確定選擇。
示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
btnListViewSingle.setOnClickListener(
new
View.OnClickListener() {
@Override
public
void
onClick(View v) {
// TODO Auto-generated method stub
AlertDialog.Builder builder =
new
AlertDialog.Builder(
MainActivity.
this
);
builder.setTitle(
"請選擇一下城市"
);
builder.setSingleChoiceItems(items,
1
,
new
OnClickListener() {
@Override
public
void
onClick(DialogInterface dialog,
int
which) {
// TODO Auto-generated method stub
String select_item = items[which].toString();
Toast.makeText(MainActivity.
this
,
"選擇了--->>"
+ select_item, Toast.LENGTH_SHORT)
.show();
}
});
builder.setPositiveButton(
"確定"
,
new
OnClickListener() {
@Override
public
void
onClick(DialogInterface dialog,
int
which) {
dialog.dismiss();
}
});
builder.show();
}
});
|
效果展示:
AlterDialog多選列表
AlterDialog除了單選列表,還有多選的列表。可以使用 Builder.setMultiChoiceItems(CharSequence[] items,boolean[] checkedItems,DialogInterface.OnMultiChoiceClickListener listener),這個方法也同樣具有多樣重載,對於這個方法,items以一個數組為數據源;checkedItems是默認的選項,因為是多選列 表,所以如果設置需要全部設置,如果沒有默認選中,則傳Null;listener為多選項點擊觸發事件。
示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
btnListViewMulti.setOnClickListener(
new
View.OnClickListener() {
@Override
public
void
onClick(View v) {
// TODO Auto-generated method stub
AlertDialog.Builder builder =
new
AlertDialog.Builder(
MainActivity.
this
);
builder.setTitle(
"請選擇城市"
);
builder.setMultiChoiceItems(items,
new
boolean
[] {
true
,
false
,
true
},
new
OnMultiChoiceClickListener() {
@Override
public
void
onClick(DialogInterface dialog,
int
which,
boolean
isChecked) {
// TODO Auto-generated method stub
String select_item = items[which].toString();
Toast.makeText(MainActivity.
this
,
"選擇了--->>"
+ select_item, Toast.LENGTH_SHORT)
.show();
}
});
builder.setPositiveButton(
"確定"
,
new
OnClickListener() {
@Override
public
void
onClick(DialogInterface dialog,
int
which) {
dialog.dismiss();
}
});
builder.show();
}
});
|
效果展示:
AlertDialog自定義樣式
有些時候,Android自帶的一些樣式設置已經無法滿足需求了,那么可以使用自定義樣式,自定義個XML布局文件,用這個文件的內容作為 AlertDialog的樣式展示在屏幕上,這樣就可以靈活定制對話框了。對於定制的XML文件,可以使用 LayoutInflater.from(Context).inflate(int,ViewGroup)的方式對其進行動態加載,然后使用 Builder.setView(View)把加載的視圖與Builder對象進行關聯,最后正常show()即可。
布局代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
<LinearLayout xmlns:android=
"http://schemas.android.com/apk/res/android"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:orientation=
"vertical"
android:paddingBottom=
"@dimen/activity_vertical_margin"
android:paddingLeft=
"@dimen/activity_horizontal_margin"
android:paddingRight=
"@dimen/activity_horizontal_margin"
android:paddingTop=
"@dimen/activity_vertical_margin"
tools:context=
".MainActivity"
>
<Button
android:id=
"@+id/btnGeneral"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:text=
"普通對話框"
/>
<Button
android:id=
"@+id/btnButtons"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:text=
"多按鈕的普通對話框"
/>
<Button
android:id=
"@+id/btnListView"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:text=
"列表選擇對話框"
/>
<Button
android:id=
"@+id/btnListViewSingle"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:text=
"單選列表選擇對話框"
/>
<Button
android:id=
"@+id/btnListViewMulti"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:text=
"多選列表選擇對話框"
/>
<Button
android:id=
"@+id/btnProgressDialog"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:text=
"滾動等待對話框"
/>
<Button
android:id=
"@+id/btnProgressDialogH"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:text=
"進度條對話框"
/>
<Button
android:id=
"@+id/btnCustomDialog"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:text=
"自定義對話框"
/>
</LinearLayout>
|
實現代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
btnCustomDialog.setOnClickListener(
new
View.OnClickListener() {
@Override
public
void
onClick(View v) {
AlertDialog.Builder builder=
new
AlertDialog.Builder(MainActivity.
this
);
View view=LayoutInflater.from(MainActivity.
this
).inflate(R.layout.dialog_signin,
null
);
Button btn=(Button)view.findViewById(R.id.btnCustom);
btn.setOnClickListener(
new
View.OnClickListener() {
@Override
public
void
onClick(View v) {
// TODO Auto-generated method stub
alertDialog.dismiss();
Toast.makeText(MainActivity.
this
,
"表單填寫完成"
,
Toast.LENGTH_SHORT).show();
}
});
builder.setView(view);
alertDialog=builder.show();
}
});
|
效果展示:
ProgressDialog
有些時候,只是需要提示用戶等待,比如在執行耗時操作等的時候,可以使用進度對話框來顯示一個進度信息,提示用戶等待,這個時候可以使用 ProgressDialog。ProgressDialog的使用方式大部分可以參見ProgressBar,其實就是一個封裝了 ProgressBar的對話框。
ProgressDialog有 兩種顯示方式,一種是以一個滾動的環狀圖標,可以顯示一個標題和一段文本內容的等待對話框;另外一種是帶刻度的進度條,和常規的進度條用法一致。兩種樣式 通過ProgressDialog.setProgressStyle(int style)設置,可以通過ProgressDialog的兩個常量進行設置:STYLE_HORIZONTAL:刻度滾 動;STYLE_SPINNER:圖標滾動,默認選項。
對於圖標滾動,可以使用兩種方式實現,一種是常規的調用構造函數,再設置對應的屬性;另外一種是直接使用ProgressDialog的靜態方法show(),直接返回一個ProgressDialog對象,並且調用show()方法。
示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
btnProgressDialog.setOnClickListener(
new
View.OnClickListener() {
@Override
public
void
onClick(View v) {
// 第一種方法,使用ProgressDialog構造函數
progressDialog =
new
ProgressDialog(MainActivity.
this
);
progressDialog.setIcon(R.drawable.ic_launcher);
progressDialog.setTitle(
"等待"
);
progressDialog.setMessage(
"正在加載...."
);
progressDialog.show();
//第二種方法,使用靜態的show方法
//progressDialog=ProgressDialog.show(MainActivity.this, "等待", "正在加載....", false, false);
new
Thread(
new
Runnable() {
@Override
public
void
run() {
try
{
Thread.sleep(
5000
);
}
catch
(Exception e) {
e.printStackTrace();
}
finally
{
progressDialog.dismiss();
}
}
}).start();
}
});
|
效果展示:
對於有刻度的ProgressDialog,除了從AlertDialog中繼承來的屬性,有一些必要的屬性需要設置,以下方法都有對於的getter方法:
- setMax(int max):最大刻度。
- setProgress(int value):第一進度。
- setSecondaryProgress(int value):第二進度。
示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
btnProgressDialog.setOnClickListener(
new
View.OnClickListener() {
@Override
public
void
onClick(View v) {
// 第一種方法,使用ProgressDialog構造函數
progressDialog =
new
ProgressDialog(MainActivity.
this
);
progressDialog.setIcon(R.drawable.ic_launcher);
progressDialog.setTitle(
"等待"
);
progressDialog.setMessage(
"正在加載...."
);
progressDialog.show();
//第二種方法,使用靜態的show方法
//progressDialog=ProgressDialog.show(MainActivity.this, "等待", "正在加載....", false, false);
new
Thread(
new
Runnable() {
@Override
public
void
run() {
try
{
Thread.sleep(
5000
);
}
catch
(Exception e) {
e.printStackTrace();
}
finally
{
progressDialog.dismiss();
}
}
}).start();
}
});
|
效果展示:
總結
以上就介紹了常用的對話框的內容,DatePickerDialog和TimePickerDialog在另外一篇博客中有介紹到,可以看看:Android--UI之DatePicker、TimePicker... 。 從最新的官方文檔上了解到,推薦使用FragmentDialog來操作Dialog,這樣便於管理,有關Fragment的內容,還沒有介紹,以后介紹 了Fragment之后再說說怎么使用FragmentDialog來創建對話框。在源碼里有一個FragmentDialog的簡單例子,有興趣的可以 下載下來看看。
二、自定義Dialog的介紹(步驟清晰)
轉自:http://blog.csdn.net/fancylovejava/article/details/21617553
代碼:
package angel.devil;
import android.app.Activity;
import android.app.Dialog;
import android.os.Bundle;
import android.view.Gravity;
import android.view.Window;
import android.view.WindowManager;
public class DialogDemoActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Dialog dialog = new Dialog(this);
// setContentView可以設置為一個View也可以簡單地指定資源ID
// LayoutInflater
// li=(LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE);
// View v=li.inflate(R.layout.dialog_layout, null);
// dialog.setContentView(v);
dialog.setContentView(R.layout.dialog_layout);
dialog.setTitle("Custom Dialog");
/*
* 獲取對話框的窗口對象及參數對象以修改對話框的布局設置,
* 可以直接調用getWindow(),表示獲得這個Activity的Window
* 對象,這樣這可以以同樣的方式改變這個Activity的屬性.
*/
Window dialogWindow = dialog.getWindow();
WindowManager.LayoutParams lp = dialogWindow.getAttributes();
dialogWindow.setGravity(Gravity.LEFT | Gravity.TOP);
/*
* lp.x與lp.y表示相對於原始位置的偏移.
* 當參數值包含Gravity.LEFT時,對話框出現在左邊,所以lp.x就表示相對左邊的偏移,負值忽略.
* 當參數值包含Gravity.RIGHT時,對話框出現在右邊,所以lp.x就表示相對右邊的偏移,負值忽略.
* 當參數值包含Gravity.TOP時,對話框出現在上邊,所以lp.y就表示相對上邊的偏移,負值忽略.
* 當參數值包含Gravity.BOTTOM時,對話框出現在下邊,所以lp.y就表示相對下邊的偏移,負值忽略.
* 當參數值包含Gravity.CENTER_HORIZONTAL時
* ,對話框水平居中,所以lp.x就表示在水平居中的位置移動lp.x像素,正值向右移動,負值向左移動.
* 當參數值包含Gravity.CENTER_VERTICAL時
* ,對話框垂直居中,所以lp.y就表示在垂直居中的位置移動lp.y像素,正值向右移動,負值向左移動.
* gravity的默認值為Gravity.CENTER,即Gravity.CENTER_HORIZONTAL |
* Gravity.CENTER_VERTICAL.
*
* 本來setGravity的參數值為Gravity.LEFT | Gravity.TOP時對話框應出現在程序的左上角,但在
* 我手機上測試時發現距左邊與上邊都有一小段距離,而且垂直坐標把程序標題欄也計算在內了,
* Gravity.LEFT, Gravity.TOP, Gravity.BOTTOM與Gravity.RIGHT都是如此,據邊界有一小段距離
*/
lp.x = 100; // 新位置X坐標
lp.y = 100; // 新位置Y坐標
lp.width = 300; // 寬度
lp.height = 300; // 高度
lp.alpha = 0.7f; // 透明度
// 當Window的Attributes改變時系統會調用此函數,可以直接調用以應用上面對窗口參數的更改,也可以用setAttributes
// dialog.onWindowAttributesChanged(lp);
dialogWindow.setAttributes(lp);
/*
* 將對話框的大小按屏幕大小的百分比設置
*/
// WindowManager m = getWindowManager();
// Display d = m.getDefaultDisplay(); // 獲取屏幕寬、高用
// WindowManager.LayoutParams p = dialogWindow.getAttributes(); // 獲取對話框當前的參數值
// p.height = (int) (d.getHeight() * 0.6); // 高度設置為屏幕的0.6
// p.width = (int) (d.getWidth() * 0.65); // 寬度設置為屏幕的0.65
// dialogWindow.setAttributes(p);
dialog.show();
}
}
布局文件:
main.xml
<?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:background="#00FF00"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello" />
</LinearLayout>
dialog_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layout_root"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:padding="10dp" >
<ImageView
android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:src="@drawable/ic_launcher" />
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="A Dialog"
android:textColor="#FFF" />
</LinearLayout>
2、Android自定義Dialog
Corn
專注Android領域開發。 仰望星空,同時需要腳踏實地。 ——Android交流群:343816731
Android開發過程中,常常會遇到一些需求場景——在界面上彈出一個彈框,對用戶進行提醒並讓用戶進行某些選擇性的操作,
如退出登錄時的彈窗,讓用戶選擇“退出”還是“取消”等操作。
Android系統提供了Dialog類,以及Dialog的子類,常見如AlertDialog來實現此類功能。
一般情況下,利用Android提供的Dialog及其子類能夠滿足多數此類需求,然而,其不足之處體現在:
1. 基於Android提供的Dialog及其子類樣式單一,風格上與App本身風格可能不太協調;
2. Dialog彈窗在布局和功能上有所限制,有時不一定能滿足實際的業務需求。
本文將通過在Dialog基礎上構建自定義的Dialog彈窗,以最常見的確認彈框為例。
本樣式相對比較簡單:上面有一個彈框標題(提示語),下面左右分別是“確認”和“取消”按鈕,當用戶點擊“確認”按鈕時,彈框執行
相應的確認邏輯,當點擊“取消”按鈕時,執行相應的取消邏輯。
首先,自定義彈框樣式:
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="wrap_content" 5 android:background="@drawable/dialog_bg" 6 android:orientation="vertical" > 7 8 <TextView 9 android:id="@+id/title" 10 android:layout_width="wrap_content" 11 android:layout_height="wrap_content" 12 android:layout_gravity="center" 13 android:paddingTop="14dp" 14 android:textColor="@color/login_hint" 15 android:textSize="@dimen/text_size_18" /> 16 17 <LinearLayout 18 android:layout_width="match_parent" 19 android:layout_height="wrap_content" 20 android:layout_marginBottom="14dp" 21 android:layout_marginLeft="20dp" 22 android:layout_marginRight="20dp" 23 android:layout_marginTop="30dp" > 24 25 <TextView 26 android:id="@+id/confirm" 27 android:layout_width="wrap_content" 28 android:layout_height="wrap_content" 29 android:layout_marginRight="10dp" 30 android:layout_weight="1" 31 android:background="@drawable/btn_confirm_selector" 32 android:gravity="center" 33 android:textColor="@color/white" 34 android:textSize="@dimen/text_size_16" /> 35 36 <TextView 37 android:id="@+id/cancel" 38 android:layout_width="wrap_content" 39 android:layout_height="wrap_content" 40 android:layout_marginLeft="10dp" 41 android:layout_weight="1" 42 android:background="@drawable/btn_cancel_selector" 43 android:gravity="center" 44 android:textColor="@color/login_hint" 45 android:textSize="@dimen/text_size_16" /> 46 </LinearLayout> 47 48 </LinearLayout>
然后,通過繼承Dialog類構建確認彈框控件ConfirmDialog:
1 package com.corn.widget; 2 3 import android.app.Dialog; 4 import android.content.Context; 5 import android.os.Bundle; 6 import android.util.DisplayMetrics; 7 import android.view.LayoutInflater; 8 import android.view.View; 9 import android.view.Window; 10 import android.view.WindowManager; 11 import android.widget.TextView; 12 13 import com.corn.R; 14 15 public class ConfirmDialog extends Dialog { 16 17 private Context context; 18 private String title; 19 private String confirmButtonText; 20 private String cacelButtonText; 21 private ClickListenerInterface clickListenerInterface; 22 23 public interface ClickListenerInterface { 24 25 public void doConfirm(); 26 27 public void doCancel(); 28 } 29 30 public ConfirmDialog(Context context, String title, String confirmButtonText, String cacelButtonText) { 31 super(context, R.style.MyDialog); 32 this.context = context; 33 this.title = title; 34 this.confirmButtonText = confirmButtonText; 35 this.cacelButtonText = cacelButtonText; 36 } 37 38 @Override 39 PROTECTEDvoid onCreate(Bundle savedInstanceState) { 40 // TODO Auto-generated method stub 41 SUPER
.onCreate(savedInstanceState); 42 43 init(); 44 } 45 46 public void init() { 47 LayoutInflater inflater = LayoutInflater.from(context); 48 View view = inflater.inflate(R.layout.confirm_dialog, null); 49 setContentView(view); 50 51 TextView tvTitle = (TextView) view.findViewById(R.id.title); 52 TextView tvConfirm = (TextView) view.findViewById(R.id.confirm); 53 TextView tvCancel = (TextView) view.findViewById(R.id.cancel); 54 55 tvTitle.setText(title); 56 tvConfirm.setText(confirmButtonText); 57 tvCancel.setText(cacelButtonText); 58 59 tvConfirm.setOnClickListener(new clickListener()); 60 tvCancel.setOnClickListener(new clickListener()); 61 62 Window dialogWindow = getWindow(); 63 WindowManager.LayoutParams lp = dialogWindow.getAttributes(); 64 DisplayMetrics d = context.getResources().getDisplayMetrics(); // 獲取屏幕寬、高用 65 lp.width = (int) (d.widthPixels * 0.8); // 高度設置為屏幕的0.6 66 dialogWindow.setAttributes(lp); 67 } 68 69 public void setClicklistener(ClickListenerInterface clickListenerInterface) { 70 this.clickListenerInterface = clickListenerInterface; 71 } 72 73 private class clickListener implements View.OnClickListener { 74 @Override 75 public void onClick(View v) { 76 // TODO Auto-generated method stub 77 int id = v.getId(); 78 switch (id) { 79 case R.id.confirm: 80 clickListenerInterface.doConfirm(); 81 break; 82 case R.id.cancel: 83 clickListenerInterface.doCancel(); 84 break; 85 } 86 } 87 88 }; 89 90 }
在如上空間構造代碼中,由於控件的"確認"和"取消"邏輯與實際的應用場景有關,因此,控件中通過定義內部接口來實現。
在需要使用此控件的地方,進行如下形式調用:
1 public static void Exit(FINALContext context) { 2 final ConfirmDialog confirmDialog = new ConfirmDialog(context, "確定要退出嗎?", "退出", "取消"); 3 confirmDialog.show(); 4 confirmDialog.setClicklistener(new ConfirmDialog.ClickListenerInterface() { 5 @Override 6 public void doConfirm() { 7 // TODO Auto-generated method stub 8 confirmDialog.dismiss(); 9 //toUserHome(context); 10 AppManager.getAppManager().AppExit(context); 11 } 12 13 @Override 14 public void doCancel() { 15 // TODO Auto-generated method stub 16 confirmDialog.dismiss(); 17 } 18 }); 19 }
調用中實現了此控件的內部接口,並賦給控件本身,以此在點擊按鈕時實現基於外部具體業務邏輯的函數回調。