自定义 Android 对话框 (AlertDialog) 的样式(转载)

尊重他人劳动成果,转载请注明出处。

转自:http://www.open-open.com/lib/view/open1325635738437.html

Android 提供了 AlertDialog 类可通过其内部类 Builder 轻松创建对话框窗口,但是没法对这个对话框窗口进行定制,为了修改 AlertDialog 窗口显示的外观,解决的办法就是创建一个指定的 AlertDialog 和 AlertDialog.Builder 类。

Android default Dialog

定义外观

我们希望将上面默认的对话框外观修改为如下图所示的新对话框风格:

Custom Android Dialog

该对话框将支持下面特性:

  1. 可从资源或者字符串直接指定对话框标题
  2. 可从资源、字符串和自定义布局来设置对话框内容
  3. 可设置按钮和相应的事件处理

 编写布局、样式和主题

该对话框使用一个定制的布局来输出内容,布局定义的id将用于访问标题 TextView,下面是定义文件:

 1 <?xml version="1.0" encoding="utf-8"?>
2
3 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
4 android:orientation="vertical"
5 android:layout_width="fill_parent"
6 android:minWidth="280dip"
7 android:layout_height="wrap_content">
8
9
10
11 <LinearLayout
12      android:orientation="vertical"
13 android:background="@drawable/header"
14 android:layout_width="fill_parent"
15 android:layout_height="wrap_content">
16
17
18 <TextView
19        style="@style/DialogText.Title"
20 android:id="@+id/title"
21 android:paddingRight="8dip"
22 android:paddingLeft="8dip"
23 android:background="@drawable/title"
24 android:layout_width="wrap_content"
25 android:layout_height="wrap_content"/>
26
27 </LinearLayout>
28
29 <LinearLayout
30      android:id="@+id/content"
31 android:orientation="vertical"
32 android:background="@drawable/center"
33 android:layout_width="fill_parent"
34 android:layout_height="wrap_content">
35
36 <TextView
37        style="@style/DialogText"
38 android:id="@+id/message"
39 android:padding="5dip"
40 android:layout_width="fill_parent"
41 android:layout_height="wrap_content"/>
42
43 </LinearLayout>
44
45 <LinearLayout
46      android:orientation="horizontal"
47 android:background="@drawable/footer"
48 android:layout_width="fill_parent"
49 android:layout_height="wrap_content">
50
51 <Button
52        android:id="@+id/positiveButton"
53 android:layout_marginTop="3dip"
54 android:layout_width="0dip"
55 android:layout_weight="1"
56 android:layout_height="wrap_content"
57 android:singleLine="true"/>
58
59 <Button
60 android:id="@+id/negativeButton"
61 android:layout_marginTop="3dip"
62 android:layout_width="0dip"
63 android:layout_weight="1"
64 android:layout_height="wrap_content"
65 android:singleLine="true"/>
66
67 </LinearLayout>
68
69 </LinearLayout>

根节点 LinearLayout 的宽度设置为 fill_parent 而最小的宽度是 280dip ,因此对话框的宽度将始终为屏幕宽度的 87.5%

自定义的主题用于声明对话框是浮动的,而且使用自定义的背景和标题视图:

 1 <?xml version="1.0" encoding="utf-8"?>
2 <resources>
3
4 <style name="Dialog" parent="android:style/Theme.Dialog">
5 <item name="android:windowBackground">@null</item>
6
7 <item name="android:windowNoTitle">true</item>
8 <item name="android:windowIsFloating">true</item>
9 </style>
10
11 </resources>

接下来我们需要定义对话框的标题和消息的显示:

 1 <?xml version="1.0" encoding="utf-8"?>
2 <resources>
3
4 <style name="DialogText">
5 <item name="android:textColor">#FF000000</item>
6
7 <item name="android:textSize">12sp</item>
8 </style>
9
10 <style name="DialogText.Title">
11 <item name="android:textSize">16sp</item>
12
13 <item name="android:textStyle">bold</item>
14 </style>
15
16 </resources>

编写对话框和 Builder 类

最好我们要提供跟 AletDialog.Builder 类一样的方法:

  1 package net.androgames.blog.sample.customdialog.dialog;
2
3 import net.androgames.blog.sample.customdialog.R;
4 import android.app.Dialog;
5 import android.content.Context;
6 import android.content.DialogInterface;
7 import android.view.LayoutInflater;
8 import android.view.View;
9 import android.view.ViewGroup.LayoutParams;
10 import android.widget.Button;
11 import android.widget.LinearLayout;
12 import android.widget.TextView;
13
14 /**
15 *
16 * Create custom Dialog windows for your application
17 * Custom dialogs rely on custom layouts wich allow you to
18 * create and use your own look & feel.
19 *
20 * Under GPL v3 : http://www.gnu.org/licenses/gpl-3.0.html
21 *
22 * @author antoine vianey
23 *
24 */
25 public class CustomDialog extends Dialog {
26
27 public CustomDialog(Context context, int theme) {
28 super(context, theme);
29 }
30
31 public CustomDialog(Context context) {
32 super(context);
33 }
34
35 /**
36 * Helper class for creating a custom dialog
37 */
38 public static class Builder {
39
40 private Context context;
41 private String title;
42 private String message;
43 private String positiveButtonText;
44 private String negativeButtonText;
45 private View contentView;
46
47 private DialogInterface.OnClickListener
48 positiveButtonClickListener,
49 negativeButtonClickListener;
50
51 public Builder(Context context) {
52 this.context = context;
53 }
54
55 /**
56 * Set the Dialog message from String
57 * @param title
58 * @return
59 */
60 public Builder setMessage(String message) {
61 this.message = message;
62 return this;
63 }
64
65 /**
66 * Set the Dialog message from resource
67 * @param title
68 * @return
69 */
70 public Builder setMessage(int message) {
71 this.message = (String) context.getText(message);
72 return this;
73 }
74
75 /**
76 * Set the Dialog title from resource
77 * @param title
78 * @return
79 */
80 public Builder setTitle(int title) {
81 this.title = (String) context.getText(title);
82 return this;
83 }
84
85 /**
86 * Set the Dialog title from String
87 * @param title
88 * @return
89 */
90 public Builder setTitle(String title) {
91 this.title = title;
92 return this;
93 }
94
95 /**
96 * Set a custom content view for the Dialog.
97 * If a message is set, the contentView is not
98 * added to the Dialog...
99 * @param v
100 * @return
101 */
102 public Builder setContentView(View v) {
103 this.contentView = v;
104 return this;
105 }
106
107 /**
108 * Set the positive button resource and it's listener
109 * @param positiveButtonText
110 * @param listener
111 * @return
112 */
113 public Builder setPositiveButton(int positiveButtonText,
114 DialogInterface.OnClickListener listener) {
115 this.positiveButtonText = (String) context
116 .getText(positiveButtonText);
117 this.positiveButtonClickListener = listener;
118 return this;
119 }
120
121 /**
122 * Set the positive button text and it's listener
123 * @param positiveButtonText
124 * @param listener
125 * @return
126 */
127 public Builder setPositiveButton(String positiveButtonText,
128 DialogInterface.OnClickListener listener) {
129 this.positiveButtonText = positiveButtonText;
130 this.positiveButtonClickListener = listener;
131 return this;
132 }
133
134 /**
135 * Set the negative button resource and it's listener
136 * @param negativeButtonText
137 * @param listener
138 * @return
139 */
140 public Builder setNegativeButton(int negativeButtonText,
141 DialogInterface.OnClickListener listener) {
142 this.negativeButtonText = (String) context
143 .getText(negativeButtonText);
144 this.negativeButtonClickListener = listener;
145 return this;
146 }
147
148 /**
149 * Set the negative button text and it's listener
150 * @param negativeButtonText
151 * @param listener
152 * @return
153 */
154 public Builder setNegativeButton(String negativeButtonText,
155 DialogInterface.OnClickListener listener) {
156 this.negativeButtonText = negativeButtonText;
157 this.negativeButtonClickListener = listener;
158 return this;
159 }
160
161 /**
162 * Create the custom dialog
163 */
164 public CustomDialog create() {
165 LayoutInflater inflater = (LayoutInflater) context
166 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
167 // instantiate the dialog with the custom Theme
168 final CustomDialog dialog = new CustomDialog(context,
169 R.style.Dialog);
170 View layout = inflater.inflate(R.layout.dialog, null);
171 dialog.addContentView(layout, new LayoutParams(
172 LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
173 // set the dialog title
174 ((TextView) layout.findViewById(R.id.title)).setText(title);
175 // set the confirm button
176 if (positiveButtonText != null) {
177 ((Button) layout.findViewById(R.id.positiveButton))
178 .setText(positiveButtonText);
179 if (positiveButtonClickListener != null) {
180 ((Button) layout.findViewById(R.id.positiveButton))
181 .setOnClickListener(new View.OnClickListener() {
182 public void onClick(View v) {
183 positiveButtonClickListener.onClick(
184 dialog,
185 DialogInterface.BUTTON_POSITIVE);
186 }
187 });
188 }
189 } else {
190 // if no confirm button just set the visibility to GONE
191 layout.findViewById(R.id.positiveButton).setVisibility(
192 View.GONE);
193 }
194 // set the cancel button
195 if (negativeButtonText != null) {
196 ((Button) layout.findViewById(R.id.negativeButton))
197 .setText(negativeButtonText);
198 if (negativeButtonClickListener != null) {
199 ((Button) layout.findViewById(R.id.negativeButton))
200 .setOnClickListener(new View.OnClickListener() {
201 public void onClick(View v) {
202 positiveButtonClickListener.onClick(
203 dialog,
204 DialogInterface.BUTTON_NEGATIVE);
205 }
206 });
207 }
208 } else {
209 // if no confirm button just set the visibility to GONE
210 layout.findViewById(R.id.negativeButton).setVisibility(
211 View.GONE);
212 }
213 // set the content message
214 if (message != null) {
215 ((TextView) layout.findViewById(
216 R.id.message)).setText(message);
217 } else if (contentView != null) {
218 // if no message set
219 // add the contentView to the dialog body
220 ((LinearLayout) layout.findViewById(R.id.content))
221 .removeAllViews();
222 ((LinearLayout) layout.findViewById(R.id.content))
223 .addView(contentView,
224 new LayoutParams(
225 LayoutParams.WRAP_CONTENT,
226 LayoutParams.WRAP_CONTENT));
227 }
228 dialog.setContentView(layout);
229 return dialog;
230 }
231
232 }
233
234 }

使用自定义的 Builder

使用方法很简单:

 1 /**
2 * Build the desired Dialog
3 * CUSTOM or DEFAULT
4 */
5 @Override
6 public Dialog onCreateDialog(int dialogId) {
7 Dialog dialog = null;
8 switch (dialogId) {
9 case CUSTOM_DIALOG :
10 CustomDialog.Builder customBuilder = new
11 CustomDialog.Builder(CustomDialogActivity.this);
12 customBuilder.setTitle("Custom title")
13 .setMessage("Custom body")
14 .setNegativeButton("Cancel",
15 new DialogInterface.OnClickListener() {
16 public void onClick(DialogInterface dialog, int which) {
17 CustomDialogActivity.this
18 .dismissDialog(CUSTOM_DIALOG);
19 }
20 })
21 .setPositiveButton("Confirm",
22 new DialogInterface.OnClickListener() {
23 public void onClick(DialogInterface dialog, int which) {
24 dialog.dismiss();
25 }
26 });
27 dialog = customBuilder.create();
28 break;
29 case DEFAULT_DIALOG :
30 AlertDialog.Builder alertBuilder = new
31 AlertDialog.Builder(CustomDialogActivity.this);
32 alertBuilder.setTitle("Default title")
33 .setMessage("Default body")
34 .setNegativeButton("Cancel",
35 new DialogInterface.OnClickListener() {
36 public void onClick(DialogInterface dialog, int which) {
37 dialog.dismiss();
38 }
39 })
40 .setPositiveButton("Confirm",
41 new DialogInterface.OnClickListener() {
42 public void onClick(DialogInterface dialog, int which) {
43 CustomDialogActivity.this
44 .dismissDialog(DEFAULT_DIALOG);
45 }
46 });
47 dialog = alertBuilder.create();
48 break;
49 }
50 return dialog;
51 }

完整的代码下载: SampleCustomDialog

Enjoy !

http://blog.androgames.net/10/custom-android-dialog/










posted @ 2012-03-29 11:04  南湖虫子  阅读(4301)  评论(0编辑  收藏  举报