在Android中經常要使用Dialog來實現一些提示以及一些特殊的效果,而且樣式也不一樣,每次都得查一大堆資料,還不一定能解決,這裏總結一些常用的Dialog的實踐。
普通的Dialog
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
//普通的AlertDialog對話框
findViewById(R.id.btn_common).setOnClickListener(
new
View.OnClickListener() {
@Override
public
void
onClick(View v) {
AlertDialog.Builder builder =
new
AlertDialog.Builder(MainActivity.
this
);
builder.setTitle(
"普通的對話框的標題"
);
builder.setMessage(
"這是一個普通的對話框的內容"
);
builder.setNegativeButton(
"取消"
,
new
DialogInterface.OnClickListener() {
@Override
public
void
onClick(DialogInterface dialog,
int
which) {
toast(
"取消"
);
}
});
builder.setPositiveButton(
"確定"
,
new
DialogInterface.OnClickListener() {
@Override
public
void
onClick(DialogInterface dialog,
int
which) {
toast(
"確定"
);
}
});
AlertDialog dialog = builder.create();
dialog.show();
}
});
|
這裏使用AlertDialog來顯示一個系統的提示對話框,效果如下:
修改普通對話框的位置、大小、透明度
主要是在普通的dialog.show() 下面加上如下代碼
1
2
3
4
5
6
7
8
9
10
11
12
13
|
//放在show()之後,不然有些屬性是沒有效果的,比如height和width
Window dialogWindow = dialog.getWindow();
WindowManager m = getWindowManager();
Display d = m.getDefaultDisplay();
// 獲取屏幕寬、高用
WindowManager.LayoutParams p = dialogWindow.getAttributes();
// 獲取對話框當前的參數值
//設置高度和寬度
p.height = (
int
) (d.getHeight() *
0.4
);
// 高度設置爲屏幕的0.6
p.width = (
int
) (d.getWidth() *
0.6
);
// 寬度設置爲屏幕的0.65
//設置位置
p.gravity = Gravity.BOTTOM;
//設置透明度
p.alpha =
0
.5f;
dialogWindow.setAttributes(p);
|
在這裏,設置dialog的高爲屏幕的高度的4/10,寬爲屏幕寬帶的6/10,同事位置爲底部,透明度爲半透明。當然還有很多其他屬性,這裏暫不介紹,你們可以自己試一試。效果如下:
使用普通的dialog來添加自定義佈局
我們需自定義一個佈局,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
<
LinearLayout
android:layout_width
=
"100dp"
android:layout_height
=
"100dp"
android:background
=
"#00ff00"
>
<
TextView
android:layout_width
=
"match_parent"
android:layout_height
=
"match_parent"
android:gravity
=
"center"
android:textColor
=
"#ff0000"
android:text
=
"你好"
/>
</
LinearLayout
>
|
我們這裏新建了一個佈局設置高度和寬度爲100dp,線性佈局裏面包裹了一個TextView,佈局很簡單,當然也可以自定義一個複雜的佈局,這裏就不介紹了。來看看Java代碼的實現。
1
2
3
4
5
6
7
8
9
10
|
// 使用普通的dialog來添加自定義佈局
findViewById(R.id.btn_custom2).setOnClickListener(
new
View.OnClickListener() {
@Override
public
void
onClick(View v) {
AlertDialog.Builder builder =
new
AlertDialog.Builder(MainActivity.
this
);
builder.setView(R.layout.dialog_custom1);
AlertDialog dialog = builder.create();
dialog.show();
}
});
|
我們直接把我們的佈局通過builder設置進去,看看效果:
這裏的Dialog非常醜,這是與AlertDialog的默認主題有關,下面我們通過自定義主題來改變對話框的樣式來使對話框變得漂亮。
在values/styles.xml自定義樣式繼承Android:Theme.Dialog來實現自己的樣式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<
style
name
=
"MyCommonDialog"
parent
=
"android:Theme.Dialog"
>
<!-- 背景顏色及透明程度 -->
<
item
name
=
"android:windowBackground"
>@android:color/transparent</
item
>
<!-- 是否半透明 -->
<
item
name
=
"android:windowIsTranslucent"
>false</
item
>
<!-- 是否沒有標題 -->
<
item
name
=
"android:windowNoTitle"
>true</
item
>
<!-- 是否浮現在activity之上 -->
<
item
name
=
"android:windowIsFloating"
>true</
item
>
<!-- 是否背景模糊 -->
<
item
name
=
"android:backgroundDimEnabled"
>false</
item
>
<!-- 設置背景模糊的透明度-->
<
item
name
=
"android:backgroundDimAmount"
>0.5</
item
>
</
style
>
|
這裏樣式的屬性都有註釋,沒種樣式不是必須的,你可以自己試着改變一些值來查看效果以便達到自己的最佳效果。
在創建dialog的時候將樣式傳過去
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this,R.style.MyCommonDialog);
現在的效果如下:
可以看的我們的佈局的高度和寬帶還是沒效果,我們知道子空間的佈局一般由佈局來測量的於是我想到給這個佈局的最外層套一個佈局,看能不能達到我們的效果。
修改dialog_custom1.xml佈局如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
<
RelativeLayout
android:layout_width
=
"match_parent"
android:layout_height
=
"match_parent"
>
<
LinearLayout
android:layout_width
=
"100dp"
android:layout_height
=
"100dp"
android:layout_centerInParent
=
"true"
android:background
=
"#00ff00"
>
<
TextView
android:layout_width
=
"match_parent"
android:layout_height
=
"match_parent"
android:gravity
=
"center"
android:text
=
"你好"
android:textColor
=
"#ff0000"
/>
</
LinearLayout
>
</
RelativeLayout
>
|
再次運行如下:
達到我們想要的效果了,這樣你就可以引入樣式和自定義佈局實現各種對話框的效果了。
繼承Dialog來實現Dialog
通過繼承Dialog來實現自定義的Dialog,這樣我們就可以在任何地方直接new我們的Dialog就可以實現特定的對話框了。
1.在values/styles.xml新建一個樣式MyDialog
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<
style
name
=
"MyDialog"
parent
=
"android:Theme.Dialog"
>
<!-- 背景顏色及透明程度 -->
<
item
name
=
"android:windowBackground"
>@android:color/transparent</
item
>
<!-- 是否半透明 -->
<
item
name
=
"android:windowIsTranslucent"
>false</
item
>
<!-- 是否沒有標題 -->
<
item
name
=
"android:windowNoTitle"
>true</
item
>
<!-- 是否浮現在activity之上 -->
<
item
name
=
"android:windowIsFloating"
>true</
item
>
<!-- 是否背景模糊 -->
<
item
name
=
"android:backgroundDimEnabled"
>false</
item
>
<!-- 設置背景模糊的透明度-->
<
item
name
=
"android:backgroundDimAmount"
>0.5</
item
>
</
style
>
|
2.新建一個MyDialog繼承Dialog
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
public
class
MyDialog
extends
Dialog {
//在構造方法裏預加載我們的樣式,這樣就不用每次創建都指定樣式了
public
MyDialog(Context context) {
this
(context, R.style.MyDialog);
}
public
MyDialog(Context context,
int
themeResId) {
super
(context, themeResId);
}
@Override
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
// 預先設置Dialog的一些屬性
Window dialogWindow = getWindow();
WindowManager.LayoutParams p = dialogWindow.getAttributes();
p.x =
0
;
p.y =
100
;
p.gravity = Gravity.LEFT | Gravity.TOP;
dialogWindow.setAttributes(p);
}
}
|
/*
* 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
*/
這裏對window的一些參數進行了解釋,我把對話框設置的離左上角離頂部100px的位置。
3.使用MyDialog
自定義佈局dialog_custom2.xml
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
|
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
android:layout_width
=
"match_parent"
android:layout_height
=
"match_parent"
android:orientation
=
"vertical"
>
<
LinearLayout
android:layout_width
=
"match_parent"
android:layout_height
=
"match_parent"
android:layout_centerInParent
=
"true"
android:background
=
"#ffffff"
android:orientation
=
"vertical"
android:padding
=
"10dp"
>
<
TextView
android:layout_width
=
"match_parent"
android:layout_height
=
"wrap_content"
android:layout_margin
=
"2dp"
android:background
=
"#00ff00"
android:gravity
=
"center"
android:padding
=
"10dp"
android:text
=
"你好"
android:textColor
=
"#000000"
/>
<
TextView
android:layout_width
=
"match_parent"
android:layout_height
=
"wrap_content"
android:layout_margin
=
"2dp"
android:background
=
"#00ff00"
android:gravity
=
"center"
android:padding
=
"10dp"
android:text
=
"你好"
android:textColor
=
"#000000"
/>
<
TextView
android:layout_width
=
"match_parent"
android:layout_height
=
"wrap_content"
android:layout_margin
=
"2dp"
android:background
=
"#00ff00"
android:gravity
=
"center"
android:padding
=
"10dp"
android:text
=
"你好"
android:textColor
=
"#000000"
/>
</
LinearLayout
>
</
RelativeLayout
>
|
Java代碼
1
2
3
4
5
6
7
8
9
|
//繼承Dialog來實現Dialog
findViewById(R.id.btn_custom3).setOnClickListener(
new
View.OnClickListener() {
@Override
public
void
onClick(View v) {
MyDialog dialog =
new
MyDialog(MainActivity.
this
);
dialog.setContentView(R.layout.dialog_custom2);
dialog.show();
}
});
|
4.查看效果:
給Dialog設置動畫
1.新建動畫文件
進入動畫dialog_enter.xml
1
2
3
4
5
6
7
8
|
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
<
translate
android:duration
=
"200"
android:fillAfter
=
"true"
android:fromYDelta
=
"100%p"
android:toYDelta
=
"0%"
/>
</
set
>
|
退出動畫dialog_exit.xml
1
2
3
4
5
6
7
8
|
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
<
translate
android:duration
=
"200"
android:fillAfter
=
"true"
android:fromYDelta
=
"0%"
android:toYDelta
=
"100%p"
/>
</
set
>
|
2.在values/styles.xml中新建樣式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
<
style
name
=
"MyAnimDialog"
parent
=
"android:Theme.Dialog"
>
<!-- 背景顏色及透明程度 -->
<
item
name
=
"android:windowBackground"
>@android:color/transparent</
item
>
<!-- 是否半透明 -->
<
item
name
=
"android:windowIsTranslucent"
>false</
item
>
<!-- 是否沒有標題 -->
<
item
name
=
"android:windowNoTitle"
>true</
item
>
<!-- 是否浮現在activity之上 -->
<
item
name
=
"android:windowIsFloating"
>true</
item
>
<!-- 是否背景模糊 -->
<
item
name
=
"android:backgroundDimEnabled"
>true</
item
>
<!-- 設置背景模糊的透明度-->
<
item
name
=
"android:backgroundDimAmount"
>0.5</
item
>
<!-- 動畫 -->
<
item
name
=
"android:windowAnimationStyle"
>@style/dialog_animation</
item
>
</
style
>
<!-- 對話框顯示和退出動畫 -->
<
style
name
=
"dialog_animation"
>
<
item
name
=
"android:windowEnterAnimation"
>@anim/dialog_enter</
item
>
<
item
name
=
"android:windowExitAnimation"
>@anim/dialog_exit</
item
>
</
style
>
|
主要是給android:windowAnimationStyle指定我們新建的動畫即可,引用和前面一樣,這裏就給出了,
3.查看效果
繼承Dialog來實現底部彈出Dialog
自定義MyBottomDialog
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
|
public
class
MyBottomDialog
extends
Dialog {
public
MyBottomDialog(Context context) {
this
(context, R.style.MyAnimDialog);
}
public
MyBottomDialog(Context context,
int
themeResId) {
super
(context, themeResId);
//加載佈局並給佈局的控件設置點擊事件
View contentView = getLayoutInflater().inflate(R.layout.dialog_custom3,
null
);
contentView.findViewById(R.id.tv_1).setOnClickListener(
new
View.OnClickListener() {
@Override
public
void
onClick(View v) {
Toast.makeText(getContext(),
"你好"
, Toast.LENGTH_SHORT).show();
}
});
super
.setContentView(contentView);
}
@Override
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
// 預先設置Dialog的一些屬性
Window dialogWindow = getWindow();
WindowManager.LayoutParams p = dialogWindow.getAttributes();
WindowManager m = getWindow().getWindowManager();
Display d = m.getDefaultDisplay();
getWindow().setAttributes(p);
|