对话框介绍与演示样例
对话框在程序中不是必备的,可是用好对话框能对我们编写的应用增色不少。採用对话框能够大大添加应用的友好性。比較经常使用的背景是:用户登陆、网络正在下载、下载成功或者失败的提示,还有,比方:短信来了、电池没电了等等,仅仅要你想到的,能提高用户体验的,你都能够使用对话框。
首先,请大家找到文档,在右上角的搜索框中输入Dialog,依据提示,选择app.dialog。大家能够先阅读一下英文文档,大体先看看,继承于哪个类,有哪些子类等等,这对于知识的积累相当重要。不是非常难,假设你认为读不懂,能够借助有道词典。我一直认为,假设没有中国这么庞大的市场,Android不可能发展这么快,但是他们为什么就不出中文文档呢,反而出日语的文档,想不通。强烈建议他们尽快出中文的文档。
什么是Dialog
Dialog类,是一切对话框的基类,须要注意的是,Dialog类尽管能够在界面上显示,可是并不是继承于View类,而是直接从java.lang.Object開始构造出的。类似于Activity,Dialog也是有生命周期的,它的生命周期由Activity来维护。Activity负责生成、保存、恢复它。在生命周期的每个阶段都有一些回调函数供系统反向调用。
ShowDialog(int id):负责显示标示为id的Dialog,这个函数假设调用后,系统将反向调用Dialog的回调函数onCreateDialog(int id);
dismissDialog(int id):使标示为id的Dialog在界面其中消。
Dialog有两个比較常见的回调函数,onCreateDialog(int id)和onPrepareDialog(int id,Dialog dialog)。假设Activity调用了showDialog(int id)后,假设这个Dialog是第一次生成,系统将反向调用Dialog的回调函数onCreateDialog(int id),再调用onPrepareDialog(int id ,Dialog dialog),假设这个Dialog还没有生成,仅仅只是还没有显示出来,那么将不会回调onCreateDialog(int id),而是直接回调onPrepareDialog(int id,Dialog dialog)方法。onPrepareDialog(int id,Dialog dialog)方法提供了这样一套机制,当Dialog生成可是没有显示出来的时候,使得有机会在显示前对Dialog做一些改动,如对Dialog标题进行改动。
什么是AlertDialog?什么是AlertDialog.Builder?
AlertDialog是Dialog的一个直接子类,一个AlertDialog能够有两个Button或者3个Button,能够对一个AlertDialog设置title、message。不能直接通过AlertDialog的构造函数来生成一个AlertDialog,一般生成的时候都是通过它的的一个内部静态类AlertDialog.Builder来构造的。
以下才是我写这篇文章的用意,在对话框中实现自己定义视图,来提升用户体验。
给Dialog设置个性化的View(我翻译为视图)
系统中提供的太死板了,我们总是会有非常多新鲜的想法,那么怎样实现给一个Dialog自己定义一个布局呢?我们要用到LayoutInFlater,通过这个类的inflate方法,能够将一个XML的布局变成一个View实例。这样的使用方法,我们会经经常使用到,所以务必学会。然后,我们通过builder.setView(myownview)这个语句,就能够将个性化的视图放到Dialog里边去。当然,你能够传入不论什么的视图对象,比方图片框,WebView等,尽情发挥你的想象力吧。
进度条Dialog:ProgressDialog
顾名思义,这个Dialog负责给用户显示运行进度的相关情况,它是AlertDialog的一个子类,在我的演示样例代码中,我是实现默认的进度显示。当然能够配置自己的进度条。同一时候有一点,提醒大家要注意,ProgressDialog不须要Builder这个内部静态类进行构造,而是直接使用构造函数进行构造。
事实上在android其中还提供了非常多Dialog,如CharacterPickerDialog/TimePickerDialog/DatePickerDialog等,可是都不是非经常常使用。用到的,大家就自己去查把,我临时还用不到,因此就不给大家演示样例代码了,由于我时间也非常紧,做測试的话,非常费时间。假设有朋友測试了,或者正好手中有这种列子,能够回复我下,我加进来,以便其他的朋友查看,学习。
上面把Dialog的基础都说了说,说实话,懂这些还不够,远远不够,等真正开发应用的时候,假设你用了这些,就会发现你做出的应用非常难看,或者不适用。因此,做些变通还是非常必要的。
以下的图片是第一个演示样例程序的代码:有6个截图:(演示样例代码名称:AlertDialogTest1.rar)
弹出选择框(演示样例代码名称:AlertDialogTest.rar)
假设你用过新浪微博的anroidclient或者人人网的androidclient,那么你就会发现,以下截图中的效果,你是一定见过的,通常通过这样的对话框去提示用户做一些选择。那么这样的效果是怎样实现的呢?以下做简单分析。
//注意这里千万不要用this.getApplicationContext(),由于仅仅有Activity才干生成Dialog
CharSequence[] items = {"手机相冊", "手机拍照", "清除照片"};
AlertDialog imageDialog = new AlertDialog.Builder(MainActivity.this)
.setItems(items, new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int item) {
}
通过.setItems()就能够实现这样的效果,第一个參数是一个数组,第二个參数是一个回调函数,当你点击某一项时触发的事件。
这里有一点要注意,我在開始測试的时候,是这么写的:
AlertDialog imageDialog = new AlertDialog.Builder(this.getApplicationContext());
总是出错,我一直想不到错在哪里,看了错误才知道,WindowManager$BadTokenException: Unable to add window -- token null is not for an application。这里要写Activity,不能写this.getApplicationContext(),大家能够參考这篇文章,自然就明确是怎么回事了。http://www.cnblogs.com/oakpip/archive/2011/04/06/2007310.html
setItems(items, new DialogInterface.OnClickListener()
这里我们是用这种方法设置的,假设非常多怎么办,比方说从数据库中取出来得怎么办?好几十条、甚至好几千条也这样做么?想一想…当然能够了,我測试过的,没有问题,就是非常多,会有下拉条的。
事实上我们另一种方法,大家看以下。这里我通过这种方法实现的。
(參看AlertdialogTest3->MainActivity1.java)
AlertDialog能够使用自己定义的layout文件。通常在界面比較复杂的情况下使用。有时候(大多数情况下),我们仅仅是须要在alertdialog中显示一个列表并能够对相关的事件作出操作,这时候用自己定义alertdialog显得过于复杂。用setItem能够做到这一点,可是却不能改变每一个item的高度。这时候能够用setAdapter,在adapter中指定给item指定一个xml布局文件,然后在布局xml文件里定义相关样式。
builder.setAdapter(new ArrayAdapter(MainActivity.this,
android.R.layout.simple_dropdown_item_1line,items), new DialogInterface.OnClickListener(){
效果和用setItems()是一样的,这里的数据我都是用数组表示的。并没有从数据库取出来?又回到刚才的问题,假设是从数据库取出来的呢?可不能够在每一条前面加个图标呢?在后面加一个单选button呢?答案是肯定的。请看后面的介绍。
先看这样的实现方法:(參看AlertdialogTest3->MainActivity2.java)
第一幅图,仅仅有5个值,以下还空好多,可能是布局的问题,把框弄太大了;第二幅图,有15个数据,当你滑动时,会有滚动栏。第三幅图,是我在第二幅图上单击时的效果。我仅仅处理了单击事件,没处理选择事件。
当你在使用人人网的Android客户度的时候,当你要更新状态的时候,你会发现这样一个发送框,例如以下所看到的:(參看AlertdialogTest3->MainActivity3.java)
做些说明,这是我演示样例代码的效果,当点击button的时候,会弹出这个对话框,你能够输入内容,假设你没有输入不论什么内容或者输入了非常多空格,那么当你点击发送后,会提示你内容不能为空;当你正确输入内容后,会以吐丝效果显示你发送的内容,当然这是我为了測试才这样做的,你也能够实现你自己的想法,比方调用人人网的API,发送一条新奇事什么的。
最后还要介绍一点东西,去除白色边框的方法。
使用样式文件,在values 文件夹下新建styles.xml文件,编写例如以下代码:
<resources>
<style name="dialog" parent="@android:style/Theme.Dialog">
<item name="android:windowFrame">@null</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowIsTranslucent">false</item>
<item name="android:windowNoTitle">true</item>
<item name="android:background">@android:color/black</item>
<item name="android:windowBackground">@null</item>
<item name="android:backgroundDimEnabled">false</item>
</style>
</resources>
调用时,使用AlerDialog的接口类,Dialog 接口编写例如以下代码:
Dialog dialog = new Dialog(SetActivity.this, R.style.dialog);
dialog.setContentView(R.layout.test);
dialog.show();
以下我们查看一下Dialog的源代码文件,里面的构造函数为例如以下:
public Dialog(Context context, int theme) {
mContext = new ContextThemeWrapper(
context, theme == 0 ? com.android.internal.R.style.Theme_Dialog : theme);
mWindowManager = (WindowManager)context.getSystemService("window");
Window w = PolicyManager.makeNewWindow(mContext);
mWindow = w;
w.setCallback(this);
w.setWindowManager(mWindowManager, null, null);
w.setGravity(Gravity.CENTER);
mUiThread = Thread.currentThread();
mDismissCancelHandler = new DismissCancelHandler(this);
}
这里面我们能够看出,Android 使用了默认的构造函数为Dialog 设置样式,假设没有为其设置样式,即默认载入事先编写好的样式文件,Dialog 一共由多个9.png的图片构成,大部分都是带有边框的9.png图片,所以就是为什么我们上边的样式文件要将其背景去除掉。这个东西搞了我好久,希望对你有帮助。
前后效果对照
未设置前:
设置后:
以下的东西转自一个网友的文章,大家再看看,印象就更深了。
创建对话框
一个对话框通常是一个出如今当前Activity之上的一个小窗体. 处于以下的Activity失去焦点, 对话框接受全部的用户交互. 对话框一般用于提示信息和与当前应用程序直接相关的小功能.
Android API 支持下列类型的对话框对象:
警告对话框 AlertDialog: 一个能够有0到3个button, 一个单选框或复选框的列表的对话框. 警告对话框能够创建大多数的交互界面, 是推荐的类型.
进度对话框 ProgressDialog: 显示一个进度环或者一个进度条. 因为它是AlertDialog的扩展, 所以它也支持button.
日期选择对话框 DatePickerDialog: 让用户选择一个日期.
时间选择对话框 TimePickerDialog: 让用户选择一个时间.
假设你希望自己定义你的对话框, 能够扩展Dialog类.
Showing a Dialog 显示对话框
一个对话框总是被创建和显示为一个Activity的一部分. 你应该在Activity的onCreateDialog(int)中创建对话框. 当你使用这个回调函数时,Android系统自己主动管理每一个对话框的状态并将它们和Activity连接, 将Activity变为对话框的"全部者". 这样,每一个对话框从Activity继承一些属性. 比如,当一个对话框打开时, MENU键会显示Activity的菜单, 音量键会调整Activity当前使用的音频流的音量.
注意: 假设你希望在onCreateDialog()方法之外创建对话框, 它将不会依附在Activity上. 你能够使用setOwnerActivity(Activity)来将它依附在Activity上.
当你希望显示一个对话框时, 调用showDialog(int)并将对话框的id传给它.
当一个对话框第一次被请求时,Android调用onCreateDialog(int). 这里是你初始化对话框的地方. 这个回调函数传入的id和showDialog(int)同样. 创建对话框之后,将返回被创建的对象.
在对话框被显示之前,Android还会调用onPrepareDialog(int, Dialog). 假设你希望每次显示对话框时有动态更改的内容, 那么就改写这个函数. 该函数在每次一个对话框打开时都调用. 假设你不定义该函数,则对话框每次打开都是一样的. 该函数也会传入对话框的id以及你在onCreateDialog()中创建的Dialog对象.
最好的定义onCreateDialog(int) 和onPrepareDialog(int, Dialog) 的方法就是使用一个switch语句来检查传入的id. 每一个case创建对应的对话框. 比如, 一个游戏使用两个对话框: 一个来指示游戏暂停,还有一个指示游戏结束. 首先, 为它们定义ID:static final int DIALOG_PAUSED_ID = 0;
static final int DIALOG_GAMEOVER_ID = 1;
然后, 在onCreateDialog(int)中增加一个switch语句:
protected Dialog onCreateDialog(int id) {
Dialog dialog;
switch(id) {
case DIALOG_PAUSED_ID:
// do the work to define the pause Dialog
break;
case DIALOG_GAMEOVER_ID:
// do the work to define the game over Dialog
break;
default:
dialog = null;
}
return dialog;
}
注意: 在这个样例中, case语句为空由于定义Dialog的程序在后面会有介绍.
在须要显示对话框是, 调用showDialog(int), 传入对话框的id:
showDialog(DIALOG_PAUSED_ID);Dismissing a Dialog 解除对话框
当你准备关闭对话框时, 你能够使用dismiss()函数. 假设须要的话, 你也能够从Activity调用dismissDialog(int), 二者效果是一样的.
假设你使用onCreateDialog(int)来管理你的对话框的状态, 那么每次你的对话框被解除时, 该对话框对象的状态会被Activity保存. 假设你决定你不再须要这个对象或者须要清除对话框的状态, 那么你应该调用 removeDialog(int). 这将把全部该对象的内部引用移除, 假设该对话框在显示的话将被解除.
Using dismiss listeners 使用解除监听器
假设你希望在对话框解除时执行某些程序, 那么你应该给对话框附加一个解除监听器.
首先定义DialogInterface.OnDismissListener接口. 这个接口仅仅有一个方法, onDismiss(DialogInterface), 该方法将在对话框解除时被调用.
然后将你的OnDismissListener实现传给setOnDismissListener().
然而,注意对话框也能够被"取消". 这是一个特殊的情形, 它意味着对话框被用户显式的取消掉. 这将在用户按下"back"键时, 或者对话框显式的调用cancel()(按下对话框的cancelbutton)时发生. 当一个对话框被取消时, OnDismissListener将仍然被通知, 但假设你希望在对话框被显示取消(而不是正常解除)时被通知, 则你应该使用setOnCancelListener()注冊一个DialogInterface.OnCancelListener.
Creating an AlertDialog 创建警告对话框
An AlertDialog is an extension of the Dialog class. It is capable of constructing most dialog user interfaces and is the suggested dialog type. You should use it for dialogs that use any of the following features:
一个警告对话框是对话框的一个扩展. 它可以创建大多数对话框用户界面而且是推荐的对话框类新星. 对于须要下列不论什么特性的对话框,你都应该使用它:
一个标题
一条文字消息
1个-3个button
一个可选择的列表(单选框或者复选框)
要创建一个AlertDialog, 使用AlertDialog.Builder子类. 使用AlertDialog.Builder(Context)来得到一个Builder, 然后使用该类的公有方法来定义AlertDialog的属性. 设定好以后, 使用create()方法来获得AlertDialog对象.
以下的主题展示了怎样为AlertDialog定义不同的属性, 使用AlertDialog.Builder类. 假设你使用这些演示样例代码, 你能够在onCreateDialog()中返回最后的Dialog对象来获得图片中对话框的效果.
Adding buttons 添加按钮
要创建一个如图所看到的的窗体, 使用set...Button()方法:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Are you sure you want to exit?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
MyActivity.this.finish();
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
首先,使用setMessage(CharSequence)为对话框添加一条消息。 然后, 開始连续调用方法, 使用setCancelable(boolean)将对话框设为不可取消(不能使用back键来取消)。对每个button,使用set...Button() 方法,该方法接受button名称和一个DialogInterface.OnClickListener,该监听器定义了当用户选择该button时应做的动作。
注意:对每种button类型,仅仅能为AlertDialog创建一个。也就是说,一个AlertDialog不能有两个以上的"positive"button。这使得可能的button数量最多为三个:肯定、否定、中性。这些名字和实际功能没有联系,可是将帮助你记忆它们各做什么事情。Adding a list 添加列表
要创建一个具有可选项的AlertDialog,使用setItems()方法:
final CharSequence[] items = {"Red", "Green", "Blue"};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Pick a color");
builder.setItems(items, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
Toast.makeText(getApplicationContext(), items[item], Toast.LENGTH_SHORT).show();
}
});
AlertDialog alert = builder.create();
首先添加一个标题。然后使用setItems()添加一个可选列表,该列表接受一个选项名称的列表和一个DialogInterface.OnClickListener, 后者定义了选项相应的响应。
Adding checkboxes and radio buttons 添加单选框和复选框
要创建一个带有多选列表或者单选列表的对话框, 使用setMultiChoiceItems()和setSingleChoiceItems()方法。假设你在onCreateDialog()中创建可选择列表, Android会自己主动管理列表的状态. 仅仅要activity仍然活跃, 那么对话框就会记住刚才选中的选项,但当用户退出activity时,该选择丢失。
注意: 要在你的acitivity离开和暂停时保存选择, 你必须在activity的声明周期中正确的保存和恢复设置。为了永久性保存选择,你必须使用数据存储技术中的一种。
要创建一个具有单选列表的AlertDialog,仅仅需将一个样例中的setItems()换成 setSingleChoiceItems():final CharSequence[] items = {"Red", "Green", "Blue"};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Pick a color");
builder.setSingleChoiceItems(items, -1, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
Toast.makeText(getApplicationContext(), items[item], Toast.LENGTH_SHORT).show();
}
});
AlertDialog alert = builder.create();
第二个參数是默认被选中的选项位置,使用“-1”来表示默认情况下不选中不论什么选项。
Creating a ProgressDialog 创建进度对话框
一个ProgressDialog(进度对话框)是AlertDialog的扩展。它能够显示一个进度的动画——进度环或者进度条。这个对话框也能够提供button,比如取消一个下载等。
打开一个进度对话框非常easy,仅仅须要调用 ProgressDialog.show()就可以。比如,上图的对话框能够不通过onCreateDialog(int),而直接显示:
ProgressDialog dialog = ProgressDialog.show(MyActivity.this, "",
"Loading. Please wait...", true);
第一个參数是应用程序上下文。第二个为对话框的标题(这里为空),第三个为对话框内容, 最后一个为该进度是否为不可确定的(这仅仅跟进度条的创建有关,见下一节)。
进度对话框的默认样式为一个旋转的环。假设你希望显示运行进度值,请看下一节。
Showing a progress bar 显示运行进度条
使用一个动画进度条来显示运行进度:
使用 ProgressDialog(Context)构造函数来初始化一个ProgressDialog对象。
将进度样式设置为"STYLE_HORIZONTAL",使用setProgressStyle(int)方法。而且设置其他属性,比如内容等。
在须要显示时调用show()或者从onCreateDialog(int)回调函数中返回该ProgressDialog。
你能够使用 setProgress(int)或者incrementProgressBy(int)来添加显示的进度。
比如,你的设置可能像这样:ProgressDialog progressDialog;
progressDialog = new ProgressDialog(mContext);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setMessage("Loading...");
progressDialog.setCancelable(false);
设置非常easy。大部分创建进度对话框须要的代码是在更新它的进程中。你可能须要在一个新的线程中更新它,并使用Handler来将进度报告给Activity。假设你不熟悉使用Handler和另外的线程,请看下列样例,该样例使用了一个新的线程来更新进度。
Example ProgressDialog with a second thread 例--使用一个线程来显示运行进度对话框
这个样例使用一个线程来跟踪一个进程的进度(事实上为从1数到100)。每当进度更新时,该线程通过Handler给主activity发送一个消息。主 Activity更新ProgressDialog.package com.example.progressdialog;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class NotificationTest extends Activity {
static final int PROGRESS_DIALOG = 0;
Button button;
ProgressThread progressThread;
ProgressDialog progressDialog;
/** Called when the activity is first created. */
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Setup the button that starts the progress dialog
button = (Button) findViewById(R.id.progressDialog);
button.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
showDialog(PROGRESS_DIALOG);
}
});
}
protected Dialog onCreateDialog(int id) {
switch(id) {
case PROGRESS_DIALOG:
progressDialog = new ProgressDialog(NotificationTest.this);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setMessage("Loading...");
progressThread = new ProgressThread(handler);
progressThread.start();
return progressDialog;
default:
return null;
}
}
// Define the Handler that receives messages from the thread and update the progress
final Handler handler = new Handler() {
public void handleMessage(Message msg) {
int total = msg.getData().getInt("total");
progressDialog.setProgress(total);
if (total >= 100){
dismissDialog(PROGRESS_DIALOG);
progressThread.setState(ProgressThread.STATE_DONE);
}
}
};
/** Nested class that performs progress calculations (counting) */
private class ProgressThread extends Thread {
Handler mHandler;
final static int STATE_DONE = 0;
final static int STATE_RUNNING = 1;
int mState;
int total;
ProgressThread(Handler h) {
mHandler = h;
}
public void run() {
mState = STATE_RUNNING;
total = 0;
while (mState == STATE_RUNNING) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Log.e("ERROR", "Thread Interrupted");
}
Message msg = mHandler.obtainMessage();
Bundle b = new Bundle();
b.putInt("total", total);
msg.setData(b);
mHandler.sendMessage(msg);
total++;
}
}
/* sets the current state for the thread,
* used to stop the thread */
public void setState(int state) {
mState = state;
}
}
}
Creating a Custom Dialog 创建自己定义对话框
假设你想自己定义一个对话框,你能够使用布局元素来创造你的对话框的布局。定义好布局后,将根View对象或者布局资源ID传给setContentView(View).
比如,创建如图所看到的的对话框:
创建一个xml布局custom_dialog.xml:http://schemas.android.com/apk/res/android"
android:id="@+id/layout_root"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
>
http://schemas.android.com/apk/res/android"
android:id="@+id/layout_root"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
>
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_marginRight="10dp"
/>
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:textColor="#FFF"
/>
该xml定义了一个LinearLayout中的一个ImageView 和一个TextView。
将以上布局设为对话框的content view,而且定义ImageView 和 TextView的内容:
Context mContext = getApplicationContext();
Dialog dialog = new Dialog(mContext);
dialog.setContentView(R.layout.custom_dialog);
dialog.setTitle("Custom Dialog");
TextView text = (TextView) dialog.findViewById(R.id.text);
text.setText("Hello, this is a custom dialog!");
ImageView image = (ImageView) dialog.findViewById(R.id.image);
image.setImageResource(R.drawable.android);
在初始化Dialog之后,使用setContentView(int),将布局资源id传给它。如今Dialog有一个定义好的布局,你能够使用findViewById(int)来找到该元素的id并改动它的内容。
使用前面所讲的方法显示对话框。
一个使用Dialog类建立的对话框必须有一个标题。假设你不调用setTitle(),那么标题区域会保留空白。假设你不希望有一个标题,那么你应该使用AlertDialog类来创建自己定义对话框。然而,因为一个AlertDialog使用AlertDialog.Builder类来建立最方便,所以你没有方法使用setContentView(int),而是仅仅能使用setView(View)。该方法接受一个View对象,所以你须要从xml中展开你的根View。
要展开一个xml布局,使用 getLayoutInflater() (或 getSystemService())取得LayoutInflater,然后调用inflate(int, ViewGroup),第一个參数为布局id,而第二个參数为根view的id。如今,你能够使用展开后的布局来找到View对象并定义 ImageView和TextView元素的内容。然后实例化AlertDialog.Builder并使用setView(View)来为对话框设置展开后的布局。比如:
AlertDialog.Builder builder;
AlertDialog alertDialog;
Context mContext = getApplicationContext();
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.custom_dialog,
(ViewGroup) findViewById(R.id.layout_root));
TextView text = (TextView) layout.findViewById(R.id.text);
text.setText("Hello, this is a custom dialog!");
ImageView image = (ImageView) layout.findViewById(R.id.image);
image.setImageResource(R.drawable.android);
builder = new AlertDialog.Builder(mContext);
builder.setView(layout);
alertDialog = builder.create();
使用AlertDialog来自己定义对话框,能够利用其内置特性比如button、选择列表、标题、图标等。
对话框在程序中不是必备的,可是用好对话框能对我们编写的应用增色不少。採用对话框能够大大添加应用的友好性。比較经常使用的背景是:用户登陆、网络正在下载、下载成功或者失败的提示,还有,比方:短信来了、电池没电了等等,仅仅要你想到的,能提高用户体验的,你都能够使用对话框。
首先,请大家找到文档,在右上角的搜索框中输入Dialog,依据提示,选择app.dialog。大家能够先阅读一下英文文档,大体先看看,继承于哪个类,有哪些子类等等,这对于知识的积累相当重要。不是非常难,假设你认为读不懂,能够借助有道词典。我一直认为,假设没有中国这么庞大的市场,Android不可能发展这么快,但是他们为什么就不出中文文档呢,反而出日语的文档,想不通。强烈建议他们尽快出中文的文档。
什么是Dialog
Dialog类,是一切对话框的基类,须要注意的是,Dialog类尽管能够在界面上显示,可是并不是继承于View类,而是直接从java.lang.Object開始构造出的。类似于Activity,Dialog也是有生命周期的,它的生命周期由Activity来维护。Activity负责生成、保存、恢复它。在生命周期的每个阶段都有一些回调函数供系统反向调用。
ShowDialog(int id):负责显示标示为id的Dialog,这个函数假设调用后,系统将反向调用Dialog的回调函数onCreateDialog(int id);
dismissDialog(int id):使标示为id的Dialog在界面其中消。
Dialog有两个比較常见的回调函数,onCreateDialog(int id)和onPrepareDialog(int id,Dialog dialog)。假设Activity调用了showDialog(int id)后,假设这个Dialog是第一次生成,系统将反向调用Dialog的回调函数onCreateDialog(int id),再调用onPrepareDialog(int id ,Dialog dialog),假设这个Dialog还没有生成,仅仅只是还没有显示出来,那么将不会回调onCreateDialog(int id),而是直接回调onPrepareDialog(int id,Dialog dialog)方法。onPrepareDialog(int id,Dialog dialog)方法提供了这样一套机制,当Dialog生成可是没有显示出来的时候,使得有机会在显示前对Dialog做一些改动,如对Dialog标题进行改动。
什么是AlertDialog?什么是AlertDialog.Builder?
AlertDialog是Dialog的一个直接子类,一个AlertDialog能够有两个Button或者3个Button,能够对一个AlertDialog设置title、message。不能直接通过AlertDialog的构造函数来生成一个AlertDialog,一般生成的时候都是通过它的的一个内部静态类AlertDialog.Builder来构造的。
以下才是我写这篇文章的用意,在对话框中实现自己定义视图,来提升用户体验。
给Dialog设置个性化的View(我翻译为视图)
系统中提供的太死板了,我们总是会有非常多新鲜的想法,那么怎样实现给一个Dialog自己定义一个布局呢?我们要用到LayoutInFlater,通过这个类的inflate方法,能够将一个XML的布局变成一个View实例。这样的使用方法,我们会经经常使用到,所以务必学会。然后,我们通过builder.setView(myownview)这个语句,就能够将个性化的视图放到Dialog里边去。当然,你能够传入不论什么的视图对象,比方图片框,WebView等,尽情发挥你的想象力吧。
进度条Dialog:ProgressDialog
顾名思义,这个Dialog负责给用户显示运行进度的相关情况,它是AlertDialog的一个子类,在我的演示样例代码中,我是实现默认的进度显示。当然能够配置自己的进度条。同一时候有一点,提醒大家要注意,ProgressDialog不须要Builder这个内部静态类进行构造,而是直接使用构造函数进行构造。
事实上在android其中还提供了非常多Dialog,如CharacterPickerDialog/TimePickerDialog/DatePickerDialog等,可是都不是非经常常使用。用到的,大家就自己去查把,我临时还用不到,因此就不给大家演示样例代码了,由于我时间也非常紧,做測试的话,非常费时间。假设有朋友測试了,或者正好手中有这种列子,能够回复我下,我加进来,以便其他的朋友查看,学习。
上面把Dialog的基础都说了说,说实话,懂这些还不够,远远不够,等真正开发应用的时候,假设你用了这些,就会发现你做出的应用非常难看,或者不适用。因此,做些变通还是非常必要的。
以下的图片是第一个演示样例程序的代码:有6个截图:(演示样例代码名称:AlertDialogTest1.rar)
弹出选择框(演示样例代码名称:AlertDialogTest.rar)
假设你用过新浪微博的anroidclient或者人人网的androidclient,那么你就会发现,以下截图中的效果,你是一定见过的,通常通过这样的对话框去提示用户做一些选择。那么这样的效果是怎样实现的呢?以下做简单分析。
//注意这里千万不要用this.getApplicationContext(),由于仅仅有Activity才干生成Dialog
CharSequence[] items = {"手机相冊", "手机拍照", "清除照片"};
AlertDialog imageDialog = new AlertDialog.Builder(MainActivity.this)
.setItems(items, new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int item) {
}
通过.setItems()就能够实现这样的效果,第一个參数是一个数组,第二个參数是一个回调函数,当你点击某一项时触发的事件。
这里有一点要注意,我在開始測试的时候,是这么写的:
AlertDialog imageDialog = new AlertDialog.Builder(this.getApplicationContext());
总是出错,我一直想不到错在哪里,看了错误才知道,WindowManager$BadTokenException: Unable to add window -- token null is not for an application。这里要写Activity,不能写this.getApplicationContext(),大家能够參考这篇文章,自然就明确是怎么回事了。http://www.cnblogs.com/oakpip/archive/2011/04/06/2007310.html
setItems(items, new DialogInterface.OnClickListener()
这里我们是用这种方法设置的,假设非常多怎么办,比方说从数据库中取出来得怎么办?好几十条、甚至好几千条也这样做么?想一想…当然能够了,我測试过的,没有问题,就是非常多,会有下拉条的。
事实上我们另一种方法,大家看以下。这里我通过这种方法实现的。
(參看AlertdialogTest3->MainActivity1.java)
AlertDialog能够使用自己定义的layout文件。通常在界面比較复杂的情况下使用。有时候(大多数情况下),我们仅仅是须要在alertdialog中显示一个列表并能够对相关的事件作出操作,这时候用自己定义alertdialog显得过于复杂。用setItem能够做到这一点,可是却不能改变每一个item的高度。这时候能够用setAdapter,在adapter中指定给item指定一个xml布局文件,然后在布局xml文件里定义相关样式。
builder.setAdapter(new ArrayAdapter(MainActivity.this,
android.R.layout.simple_dropdown_item_1line,items), new DialogInterface.OnClickListener(){
效果和用setItems()是一样的,这里的数据我都是用数组表示的。并没有从数据库取出来?又回到刚才的问题,假设是从数据库取出来的呢?可不能够在每一条前面加个图标呢?在后面加一个单选button呢?答案是肯定的。请看后面的介绍。
先看这样的实现方法:(參看AlertdialogTest3->MainActivity2.java)
第一幅图,仅仅有5个值,以下还空好多,可能是布局的问题,把框弄太大了;第二幅图,有15个数据,当你滑动时,会有滚动栏。第三幅图,是我在第二幅图上单击时的效果。我仅仅处理了单击事件,没处理选择事件。
当你在使用人人网的Android客户度的时候,当你要更新状态的时候,你会发现这样一个发送框,例如以下所看到的:(參看AlertdialogTest3->MainActivity3.java)
做些说明,这是我演示样例代码的效果,当点击button的时候,会弹出这个对话框,你能够输入内容,假设你没有输入不论什么内容或者输入了非常多空格,那么当你点击发送后,会提示你内容不能为空;当你正确输入内容后,会以吐丝效果显示你发送的内容,当然这是我为了測试才这样做的,你也能够实现你自己的想法,比方调用人人网的API,发送一条新奇事什么的。
最后还要介绍一点东西,去除白色边框的方法。
使用样式文件,在values 文件夹下新建styles.xml文件,编写例如以下代码:
<resources>
<style name="dialog" parent="@android:style/Theme.Dialog">
<item name="android:windowFrame">@null</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowIsTranslucent">false</item>
<item name="android:windowNoTitle">true</item>
<item name="android:background">@android:color/black</item>
<item name="android:windowBackground">@null</item>
<item name="android:backgroundDimEnabled">false</item>
</style>
</resources>
调用时,使用AlerDialog的接口类,Dialog 接口编写例如以下代码:
Dialog dialog = new Dialog(SetActivity.this, R.style.dialog);
dialog.setContentView(R.layout.test);
dialog.show();
以下我们查看一下Dialog的源代码文件,里面的构造函数为例如以下:
public Dialog(Context context, int theme) {
mContext = new ContextThemeWrapper(
context, theme == 0 ? com.android.internal.R.style.Theme_Dialog : theme);
mWindowManager = (WindowManager)context.getSystemService("window");
Window w = PolicyManager.makeNewWindow(mContext);
mWindow = w;
w.setCallback(this);
w.setWindowManager(mWindowManager, null, null);
w.setGravity(Gravity.CENTER);
mUiThread = Thread.currentThread();
mDismissCancelHandler = new DismissCancelHandler(this);
}
这里面我们能够看出,Android 使用了默认的构造函数为Dialog 设置样式,假设没有为其设置样式,即默认载入事先编写好的样式文件,Dialog 一共由多个9.png的图片构成,大部分都是带有边框的9.png图片,所以就是为什么我们上边的样式文件要将其背景去除掉。这个东西搞了我好久,希望对你有帮助。
前后效果对照
未设置前:
设置后:
以下的东西转自一个网友的文章,大家再看看,印象就更深了。
创建对话框
一个对话框通常是一个出如今当前Activity之上的一个小窗体. 处于以下的Activity失去焦点, 对话框接受全部的用户交互. 对话框一般用于提示信息和与当前应用程序直接相关的小功能.
Android API 支持下列类型的对话框对象:
警告对话框 AlertDialog: 一个能够有0到3个button, 一个单选框或复选框的列表的对话框. 警告对话框能够创建大多数的交互界面, 是推荐的类型.
进度对话框 ProgressDialog: 显示一个进度环或者一个进度条. 因为它是AlertDialog的扩展, 所以它也支持button.
日期选择对话框 DatePickerDialog: 让用户选择一个日期.
时间选择对话框 TimePickerDialog: 让用户选择一个时间.
假设你希望自己定义你的对话框, 能够扩展Dialog类.
Showing a Dialog 显示对话框
一个对话框总是被创建和显示为一个Activity的一部分. 你应该在Activity的onCreateDialog(int)中创建对话框. 当你使用这个回调函数时,Android系统自己主动管理每一个对话框的状态并将它们和Activity连接, 将Activity变为对话框的"全部者". 这样,每一个对话框从Activity继承一些属性. 比如,当一个对话框打开时, MENU键会显示Activity的菜单, 音量键会调整Activity当前使用的音频流的音量.
注意: 假设你希望在onCreateDialog()方法之外创建对话框, 它将不会依附在Activity上. 你能够使用setOwnerActivity(Activity)来将它依附在Activity上.
当你希望显示一个对话框时, 调用showDialog(int)并将对话框的id传给它.
当一个对话框第一次被请求时,Android调用onCreateDialog(int). 这里是你初始化对话框的地方. 这个回调函数传入的id和showDialog(int)同样. 创建对话框之后,将返回被创建的对象.
在对话框被显示之前,Android还会调用onPrepareDialog(int, Dialog). 假设你希望每次显示对话框时有动态更改的内容, 那么就改写这个函数. 该函数在每次一个对话框打开时都调用. 假设你不定义该函数,则对话框每次打开都是一样的. 该函数也会传入对话框的id以及你在onCreateDialog()中创建的Dialog对象.
最好的定义onCreateDialog(int) 和onPrepareDialog(int, Dialog) 的方法就是使用一个switch语句来检查传入的id. 每一个case创建对应的对话框. 比如, 一个游戏使用两个对话框: 一个来指示游戏暂停,还有一个指示游戏结束. 首先, 为它们定义ID:static final int DIALOG_PAUSED_ID = 0;
static final int DIALOG_GAMEOVER_ID = 1;
然后, 在onCreateDialog(int)中增加一个switch语句:
protected Dialog onCreateDialog(int id) {
Dialog dialog;
switch(id) {
case DIALOG_PAUSED_ID:
// do the work to define the pause Dialog
break;
case DIALOG_GAMEOVER_ID:
// do the work to define the game over Dialog
break;
default:
dialog = null;
}
return dialog;
}
注意: 在这个样例中, case语句为空由于定义Dialog的程序在后面会有介绍.
在须要显示对话框是, 调用showDialog(int), 传入对话框的id:
showDialog(DIALOG_PAUSED_ID);Dismissing a Dialog 解除对话框
当你准备关闭对话框时, 你能够使用dismiss()函数. 假设须要的话, 你也能够从Activity调用dismissDialog(int), 二者效果是一样的.
假设你使用onCreateDialog(int)来管理你的对话框的状态, 那么每次你的对话框被解除时, 该对话框对象的状态会被Activity保存. 假设你决定你不再须要这个对象或者须要清除对话框的状态, 那么你应该调用 removeDialog(int). 这将把全部该对象的内部引用移除, 假设该对话框在显示的话将被解除.
Using dismiss listeners 使用解除监听器
假设你希望在对话框解除时执行某些程序, 那么你应该给对话框附加一个解除监听器.
首先定义DialogInterface.OnDismissListener接口. 这个接口仅仅有一个方法, onDismiss(DialogInterface), 该方法将在对话框解除时被调用.
然后将你的OnDismissListener实现传给setOnDismissListener().
然而,注意对话框也能够被"取消". 这是一个特殊的情形, 它意味着对话框被用户显式的取消掉. 这将在用户按下"back"键时, 或者对话框显式的调用cancel()(按下对话框的cancelbutton)时发生. 当一个对话框被取消时, OnDismissListener将仍然被通知, 但假设你希望在对话框被显示取消(而不是正常解除)时被通知, 则你应该使用setOnCancelListener()注冊一个DialogInterface.OnCancelListener.
Creating an AlertDialog 创建警告对话框
An AlertDialog is an extension of the Dialog class. It is capable of constructing most dialog user interfaces and is the suggested dialog type. You should use it for dialogs that use any of the following features:
一个警告对话框是对话框的一个扩展. 它可以创建大多数对话框用户界面而且是推荐的对话框类新星. 对于须要下列不论什么特性的对话框,你都应该使用它:
一个标题
一条文字消息
1个-3个button
一个可选择的列表(单选框或者复选框)
要创建一个AlertDialog, 使用AlertDialog.Builder子类. 使用AlertDialog.Builder(Context)来得到一个Builder, 然后使用该类的公有方法来定义AlertDialog的属性. 设定好以后, 使用create()方法来获得AlertDialog对象.
以下的主题展示了怎样为AlertDialog定义不同的属性, 使用AlertDialog.Builder类. 假设你使用这些演示样例代码, 你能够在onCreateDialog()中返回最后的Dialog对象来获得图片中对话框的效果.
Adding buttons 添加按钮
要创建一个如图所看到的的窗体, 使用set...Button()方法:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Are you sure you want to exit?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
MyActivity.this.finish();
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
首先,使用setMessage(CharSequence)为对话框添加一条消息。 然后, 開始连续调用方法, 使用setCancelable(boolean)将对话框设为不可取消(不能使用back键来取消)。对每个button,使用set...Button() 方法,该方法接受button名称和一个DialogInterface.OnClickListener,该监听器定义了当用户选择该button时应做的动作。
注意:对每种button类型,仅仅能为AlertDialog创建一个。也就是说,一个AlertDialog不能有两个以上的"positive"button。这使得可能的button数量最多为三个:肯定、否定、中性。这些名字和实际功能没有联系,可是将帮助你记忆它们各做什么事情。Adding a list 添加列表
要创建一个具有可选项的AlertDialog,使用setItems()方法:
final CharSequence[] items = {"Red", "Green", "Blue"};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Pick a color");
builder.setItems(items, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
Toast.makeText(getApplicationContext(), items[item], Toast.LENGTH_SHORT).show();
}
});
AlertDialog alert = builder.create();
首先添加一个标题。然后使用setItems()添加一个可选列表,该列表接受一个选项名称的列表和一个DialogInterface.OnClickListener, 后者定义了选项相应的响应。
Adding checkboxes and radio buttons 添加单选框和复选框
要创建一个带有多选列表或者单选列表的对话框, 使用setMultiChoiceItems()和setSingleChoiceItems()方法。假设你在onCreateDialog()中创建可选择列表, Android会自己主动管理列表的状态. 仅仅要activity仍然活跃, 那么对话框就会记住刚才选中的选项,但当用户退出activity时,该选择丢失。
注意: 要在你的acitivity离开和暂停时保存选择, 你必须在activity的声明周期中正确的保存和恢复设置。为了永久性保存选择,你必须使用数据存储技术中的一种。
要创建一个具有单选列表的AlertDialog,仅仅需将一个样例中的setItems()换成 setSingleChoiceItems():final CharSequence[] items = {"Red", "Green", "Blue"};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Pick a color");
builder.setSingleChoiceItems(items, -1, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
Toast.makeText(getApplicationContext(), items[item], Toast.LENGTH_SHORT).show();
}
});
AlertDialog alert = builder.create();
第二个參数是默认被选中的选项位置,使用“-1”来表示默认情况下不选中不论什么选项。
Creating a ProgressDialog 创建进度对话框
一个ProgressDialog(进度对话框)是AlertDialog的扩展。它能够显示一个进度的动画——进度环或者进度条。这个对话框也能够提供button,比如取消一个下载等。
打开一个进度对话框非常easy,仅仅须要调用 ProgressDialog.show()就可以。比如,上图的对话框能够不通过onCreateDialog(int),而直接显示:
ProgressDialog dialog = ProgressDialog.show(MyActivity.this, "",
"Loading. Please wait...", true);
第一个參数是应用程序上下文。第二个为对话框的标题(这里为空),第三个为对话框内容, 最后一个为该进度是否为不可确定的(这仅仅跟进度条的创建有关,见下一节)。
进度对话框的默认样式为一个旋转的环。假设你希望显示运行进度值,请看下一节。
Showing a progress bar 显示运行进度条
使用一个动画进度条来显示运行进度:
使用 ProgressDialog(Context)构造函数来初始化一个ProgressDialog对象。
将进度样式设置为"STYLE_HORIZONTAL",使用setProgressStyle(int)方法。而且设置其他属性,比如内容等。
在须要显示时调用show()或者从onCreateDialog(int)回调函数中返回该ProgressDialog。
你能够使用 setProgress(int)或者incrementProgressBy(int)来添加显示的进度。
比如,你的设置可能像这样:ProgressDialog progressDialog;
progressDialog = new ProgressDialog(mContext);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setMessage("Loading...");
progressDialog.setCancelable(false);
设置非常easy。大部分创建进度对话框须要的代码是在更新它的进程中。你可能须要在一个新的线程中更新它,并使用Handler来将进度报告给Activity。假设你不熟悉使用Handler和另外的线程,请看下列样例,该样例使用了一个新的线程来更新进度。
Example ProgressDialog with a second thread 例--使用一个线程来显示运行进度对话框
这个样例使用一个线程来跟踪一个进程的进度(事实上为从1数到100)。每当进度更新时,该线程通过Handler给主activity发送一个消息。主 Activity更新ProgressDialog.package com.example.progressdialog;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class NotificationTest extends Activity {
static final int PROGRESS_DIALOG = 0;
Button button;
ProgressThread progressThread;
ProgressDialog progressDialog;
/** Called when the activity is first created. */
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Setup the button that starts the progress dialog
button = (Button) findViewById(R.id.progressDialog);
button.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
showDialog(PROGRESS_DIALOG);
}
});
}
protected Dialog onCreateDialog(int id) {
switch(id) {
case PROGRESS_DIALOG:
progressDialog = new ProgressDialog(NotificationTest.this);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setMessage("Loading...");
progressThread = new ProgressThread(handler);
progressThread.start();
return progressDialog;
default:
return null;
}
}
// Define the Handler that receives messages from the thread and update the progress
final Handler handler = new Handler() {
public void handleMessage(Message msg) {
int total = msg.getData().getInt("total");
progressDialog.setProgress(total);
if (total >= 100){
dismissDialog(PROGRESS_DIALOG);
progressThread.setState(ProgressThread.STATE_DONE);
}
}
};
/** Nested class that performs progress calculations (counting) */
private class ProgressThread extends Thread {
Handler mHandler;
final static int STATE_DONE = 0;
final static int STATE_RUNNING = 1;
int mState;
int total;
ProgressThread(Handler h) {
mHandler = h;
}
public void run() {
mState = STATE_RUNNING;
total = 0;
while (mState == STATE_RUNNING) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Log.e("ERROR", "Thread Interrupted");
}
Message msg = mHandler.obtainMessage();
Bundle b = new Bundle();
b.putInt("total", total);
msg.setData(b);
mHandler.sendMessage(msg);
total++;
}
}
/* sets the current state for the thread,
* used to stop the thread */
public void setState(int state) {
mState = state;
}
}
}
Creating a Custom Dialog 创建自己定义对话框
假设你想自己定义一个对话框,你能够使用布局元素来创造你的对话框的布局。定义好布局后,将根View对象或者布局资源ID传给setContentView(View).
比如,创建如图所看到的的对话框:
创建一个xml布局custom_dialog.xml:http://schemas.android.com/apk/res/android"
android:id="@+id/layout_root"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
>
http://schemas.android.com/apk/res/android"
android:id="@+id/layout_root"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
>
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_marginRight="10dp"
/>
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:textColor="#FFF"
/>
该xml定义了一个LinearLayout中的一个ImageView 和一个TextView。
将以上布局设为对话框的content view,而且定义ImageView 和 TextView的内容:
Context mContext = getApplicationContext();
Dialog dialog = new Dialog(mContext);
dialog.setContentView(R.layout.custom_dialog);
dialog.setTitle("Custom Dialog");
TextView text = (TextView) dialog.findViewById(R.id.text);
text.setText("Hello, this is a custom dialog!");
ImageView image = (ImageView) dialog.findViewById(R.id.image);
image.setImageResource(R.drawable.android);
在初始化Dialog之后,使用setContentView(int),将布局资源id传给它。如今Dialog有一个定义好的布局,你能够使用findViewById(int)来找到该元素的id并改动它的内容。
使用前面所讲的方法显示对话框。
一个使用Dialog类建立的对话框必须有一个标题。假设你不调用setTitle(),那么标题区域会保留空白。假设你不希望有一个标题,那么你应该使用AlertDialog类来创建自己定义对话框。然而,因为一个AlertDialog使用AlertDialog.Builder类来建立最方便,所以你没有方法使用setContentView(int),而是仅仅能使用setView(View)。该方法接受一个View对象,所以你须要从xml中展开你的根View。
要展开一个xml布局,使用 getLayoutInflater() (或 getSystemService())取得LayoutInflater,然后调用inflate(int, ViewGroup),第一个參数为布局id,而第二个參数为根view的id。如今,你能够使用展开后的布局来找到View对象并定义 ImageView和TextView元素的内容。然后实例化AlertDialog.Builder并使用setView(View)来为对话框设置展开后的布局。比如:
AlertDialog.Builder builder;
AlertDialog alertDialog;
Context mContext = getApplicationContext();
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.custom_dialog,
(ViewGroup) findViewById(R.id.layout_root));
TextView text = (TextView) layout.findViewById(R.id.text);
text.setText("Hello, this is a custom dialog!");
ImageView image = (ImageView) layout.findViewById(R.id.image);
image.setImageResource(R.drawable.android);
builder = new AlertDialog.Builder(mContext);
builder.setView(layout);
alertDialog = builder.create();
使用AlertDialog来自己定义对话框,能够利用其内置特性比如button、选择列表、标题、图标等。