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

定义外观

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

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

  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. <LinearLayout
  10. android:orientation="vertical"
  11. android:background="@drawable/header"
  12. android:layout_width="fill_parent"
  13. android:layout_height="wrap_content">
  14.  
  15. <TextView
  16. style="@style/DialogText.Title"
  17.  
  18. android:id="@+id/title"
  19. android:paddingRight="8dip"
  20. android:paddingLeft="8dip"
  21. android:background="@drawable/title"
  22. android:layout_width="wrap_content"
  23.  
  24. android:layout_height="wrap_content"/>
  25.  
  26. </LinearLayout>
  27.  
  28. <LinearLayout
  29. android:id="@+id/content"
  30. android:orientation="vertical"
  31. android:background="@drawable/center"
  32.  
  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.  
  41. android:layout_width="fill_parent"
  42. android:layout_height="wrap_content"/>
  43.  
  44. </LinearLayout>
  45.  
  46. <LinearLayout
  47. android:orientation="horizontal"
  48. android:background="@drawable/footer"
  49.  
  50. android:layout_width="fill_parent"
  51. android:layout_height="wrap_content">
  52.  
  53. <Button
  54. android:id="@+id/positiveButton"
  55. android:layout_marginTop="3dip"
  56. android:layout_width="0dip"
  57.  
  58. android:layout_weight=""
  59. android:layout_height="wrap_content"
  60. android:singleLine="true"/>
  61.  
  62. <Button
  63. android:id="@+id/negativeButton"
  64.  
  65. android:layout_marginTop="3dip"
  66. android:layout_width="0dip"
  67. android:layout_weight=""
  68. android:layout_height="wrap_content"
  69. android:singleLine="true"/>
  70.  
  71. </LinearLayout>
  72.  
  73. </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. negativeButtonClickListener.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. }

Android 对话框 (AlertDialog)的更多相关文章

  1. 少走弯路——Android对话框AlertDialog.Builder使用方法简述

    android的自定义对话框,不需要通过继承的方式来实现,因为android已提供了相应的接口Dialog Builder ,下面就是 样例: new AlertDialog.Builder(this ...

  2. Android对话框

    这周过的实在是艰辛,自打这周二起我的本本就开始闹"罢工",最后还是重装系统了事. . .   只是可怜了我的那些被格了的软件(悲伤辣么大)!  往事不要再提,人生几度风雨... 简 ...

  3. 11.Android之常用对话框AlertDialog学习

    (1)首先我们写个简单的AlertDialog对话框,要创建一个AlertDialog,就要用到AlertDialog.Builder中的create()方法,然后创建对话框可以设置对话框的属性,比如 ...

  4. Android:AlertDialog对话框

    1.简单的ALertDialog: Dialog alertDialog = new AlertDialog.Builder(this) .setTitle("标题") .setM ...

  5. 【转】【Android】对话框 AlertDialog -- 不错不错

    原文网址:http://blog.csdn.net/feng88724/article/details/6171450 本讲介绍一下Android基本组件:对话框AlertDialog. API: j ...

  6. Android中的对话框AlertDialog使用技巧合集-转载

    Android中的对话框AlertDialog使用技巧合集     文章来自:http://blog.csdn.net/blue6626/article/details/6641105   今天我用自 ...

  7. Android——用对话框做登陆界面(自定义对话框AlertDialog,多线程,进度条ProgressDialog,ListView,GridView,SharedPreferences存,读数据,存取文本,assets文件)

    效果: 1.点击图标进入页面二 2.页面2图片暂停显示5秒进入页面三 3.点击页面三登陆按钮,打开登陆对话框,输入密码进入页面四 点击下载按钮,显示水平进度条 点击保存和获取用户名和密码 进入页面六  ...

  8. android中提示&对话框----AlertDialog

    AlertDialog(对话框) 一.对话框的基本使用流程 step1:创建AlertDialog.Buider; step2:调用setIcon()设置图标,setTitle()或者setCusto ...

  9. 【Android】Android中AlertDialog对话框的使用实例

    package com.ceac.deng; import android.R.string; import android.support.v7.app.ActionBarActivity; imp ...

随机推荐

  1. python 查找字符串中字母的个数

    2017.6.17 更新:好像知道错在哪里了.以第一个为例,输入应该是“AHHaaBBa”,因为直接输入AHHaaBBa时,系统不知到这是一个变量还是字符串,所以必须输入的时候申明定义.既然这样的话, ...

  2. Java之集合(十一)IdentityHashMap

    转载请注明源出处:http://www.cnblogs.com/lighten/p/7381905.html 1.前言 查看JDK源码总是能发现一些新东西,IdentityHashMap也是Map的一 ...

  3. Eclipse打不开 提示an error has occurred.see the log file

    有时由于Eclipse卡死,强制关闭之后会出现打不开的情况.弹窗提示: 查看log文件,发现有这样的信息:  !MESSAGE The workspace exited with unsaved ch ...

  4. Flow类

    JLS参考:https://docs.oracle.com/javase/specs/jls/se7/html/jls-16.html This pass implements dataflow an ...

  5. switch开关

    1.开关按钮 效果如下图 2.css代码 .form-switch{ display: inline-block; } .form-switch input[type="checkbox&q ...

  6. php的$GLOBALS例子

    <?php $test = "test"; function show1($abc){//直接把参数传入函数,函数能用 echo $abc.'<br>'; } f ...

  7. 关于 AXI协议的学习解释说明

    AXI(Advanced eXtensible Interface)是一种总线协议,该协议是ARM公司提出的AMBA(Advanced Microcontroller Bus Architecture ...

  8. jenkins自动化部署

    目录 typora-copy-images-to: pic Jenkins部署文档 一.安装环境 1.CentOs下安装JDK 2.CentOS安装Maven 3.CentOS安装git 4.Cent ...

  9. Fiddler——PC上实现手机的抓包(转载 http://www.jianshu.com/p/13f8a81d7c7c)

    Fiddler是15年初,在千牛中做超级促销插件时,发现没有root的Android机和没有越狱的iPhone无法修改host,因此没办法测试.为了让我这个磨人的PD也能看到,开发推荐了Fiddler ...

  10. 使用 Nginx + Tomcat 搭建负载均衡

    负载均衡 建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽.增加吞吐量.加强网络数据处理能力.提高网络的灵活性和可用性. 负载均衡,英文名称为Load Balance, ...