Dialog详解

Dialog是所有对话框的基类,但Dialog并非继承自View,而是直接从Object构造出来的。Dialog调用是异步调用,所以showDialog()时不会阻碍UI线程。

1. Activity托管对话框:
Android提供了创建对话框的快捷方式,在Activity中可以通过如showDialog(int dialogId),dismissDialog(int dialogId),onCreateDialog(),onPrepareDialog(),removeDialog()等方法来创建和管理对话框。
onCreateDialog(int dialogId)和onPrepareDialog(int dialogId, Dialog dialog)是Dialog的2个回调函数,showDialog()触发这两个回调函数的调用。[color=red]同所有的onCreate()一样,其只在Dialog第一次生成的时候才会被调用,而onPrepareDialog()在每次执行showDialog()都会被调用(不管Dialog生成了没有)。[/color]如果你想要更新对话框的内容,你只要在onPrepareDialog()中作相应的工作就可以了,该方法会在对话框显示之前进行调用。
dismissDialog()方法是用来关闭对话框的;removeDialog()方法用来将对话框从Activity的托管中移除[color=red](如果对已经移除的对话框重新进行调用showDialog ,则该对话框将进行重新创建)。[/color]

2. 常用Dialog
(1)AlertDialog
AlertDialog类是Dialog类的子类,它默认提供了3个按钮和一个文本消息,这些按钮可以按需要来使他们显示或隐藏。AlertDialog类中有一个内部静态类,名为“Builder”,Builder类提供了为对话框添加多选或单选列表,以及为这些列表添加事件处理的功能。另外,这个Builder类将AlertDialog对话框上的3个按钮按照他们的位置分别称呼为:PositiveButton, NeutralButton, NegativeButton。
(2)ProgressDialog
ProgressDialog.dialog = new ProgressDialog(context); 没有内部静态类,直接构造函数构造

3. 一个很特别的Dialog(由Activity转换而来) ,具体请参见参考doc中android.R.style部分
(1)AndroidManifest.xml中的activity的属性中增加:android :theme="@android :style/Theme.Dialog( Activity的对话框主题)。可使Activity变为Dialog(浮动窗口);
(2)AndroidManifest.xml中的activity的属性中增加:android:theme="@android:style/Theme.Translucent"(Activity半透明主题);

4. 示例代码
(1)自定义Dialog并获取Dialog中EditText的数据

public class MyDialog extends Dialog implements Button.OnClickListener {
private Button okButton, cancelButton;
private EditText nameEditText;
private MyDialogListener listener;

public MyDialog(Context context, MyDialogListener listener) {
super(context);
this.listener = listener;
}
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.mydialog);

okButton = (Button) findViewById(R.id.okButton);
cancelButton = (Button) findViewById(R.id.cancelButton);
okButton.setOnClickListener(this);
cancelButton.setOnClickListener(this);

nameEditText = (EditText) findViewById(R.id.nameEditText);
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.okButton:
listener.onOkClick(nameEditText.getText().toString());
dismiss(); // 关闭Dialog
break;
case R.id.cancelButton:
cancel(); // 取消Dialog, "取消"的含义是指不再需要执行对话框上的任何功能和动作, 取消对话框会自动调用dismiss()方法
break;
}
/*
* 当用户点击手机设备上的“返回”按钮时,屏幕上的对话框将会被取消,
* 如果你想让你的对话框不在这种情况下被取消掉的话,你可以如下设置你的对话框:setCancelable(false);
* 对话框的取消和关闭事件可以通过OnCancelListener和OnDismissListener两个监听器来被监听处理。
*/
}

}


public class MainActivity extends Activity implements MyDialogListener {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyDialog dialog = new MyDialog(this, this);
dialog.show();
}
public void onCancelClick() {
}
public void onOkClick(String name) {
Toast.makeText(this, name, Toast.LENGTH_LONG).show();
}
}

interface MyDialogListener {
public void onOkClick(String name);
public void onCancelClick();
}

mydialog.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="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/nameMessage"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Enter Name:"></TextView>
<EditText
android:id="@+id/nameEditText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="18sp"></EditText>
<LinearLayout
android:id="@+id/buttonLayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal">
<Button
android:id="@+id/okButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="OK">
</Button>
<Button
android:id="@+id/cancelButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Cancel">
</Button>
</LinearLayout>
</LinearLayout>


public class MainActivity2 extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

AlertDialog dialog = new AlertDialog.Builder(this).create();
dialog.setMessage("Do you play cricket?");
dialog.setButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case AlertDialog.BUTTON1:
break;
case AlertDialog.BUTTON2:
break;
}
}
});
dialog.setButton2("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
});
dialog.show();
}
}

托管Dialog

public class MainActivity extends Activity {
private Button button1, button2, button3, button4;
private Button.OnClickListener listener1, listener2, listener3, listener4;
private final int DIALOG1 = 1, DIALOG2 = 2, DIALOG3 = 3, DIALOG4 = 4;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
prepareListener();
}

protected Dialog onCreateDialog(int id) {
switch (id) {
case DIALOG1:
return buildDialog(this, DIALOG1);
case DIALOG2:
return buildDialog(this, DIALOG2);
case DIALOG3:
return buildDialog(this, DIALOG3);
case DIALOG4:
return buildDialog(this, DIALOG4);
}
return null;
}

protected void onPrepareDialog(int id, Dialog dialog) {
super.onPrepareDialog(id, dialog);
}

private Dialog buildDialog(Context context, int seq) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setIcon(R.drawable.alert_dialog_icon);
if (DIALOG1 == seq) {
builder.setTitle(R.string.alert_dialog_two_buttons_title);
builder.setPositiveButton(R.string.alert_dialog_ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
setTitle(R.string.alert_dialog_ok);
}
});
builder.setNegativeButton(R.string.alert_dialog_cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
setTitle(R.string.alert_dialog_cancel);
}
});
}
if (DIALOG2 == seq) {
builder.setTitle(R.string.alert_dialog_two_buttons_msg);
builder.setMessage(R.string.alert_dialog_two_buttons2_msg);

// AlertDialog最多只能有3个Button
builder.setPositiveButton(R.string.alert_dialog_ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
setTitle(R.string.alert_dialog_ok);
}
});
builder.setNeutralButton(R.string.alert_dialog_something, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
setTitle(R.string.alert_dialog_something);
}
});
builder.setNegativeButton(R.string.alert_dialog_cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
setTitle(R.string.alert_dialog_cancel);
}
});
}
if (DIALOG3 == seq) {
// LayoutInflater的inflate方法可以将一个XML布局变成一个View实例
LayoutInflater inflater = LayoutInflater.from(this);
View textEntryView = inflater.inflate(R.layout.alert_dialog_text_entry, null);
builder.setTitle(R.string.alert_dialog_text_entry);

// setView()真可以说是Dialog的一个精髓
builder.setView(textEntryView);
builder.setPositiveButton(R.string.alert_dialog_ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
setTitle(R.string.alert_dialog_ok);
}
});
builder.setNegativeButton(R.string.alert_dialog_cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
setTitle(R.string.alert_dialog_cancel);
}
});
}
if (DIALOG4 == seq) {
ProgressDialog dialog = new ProgressDialog(context);
dialog.setTitle("Downding the songs...");
dialog.setMessage("Please Waiting...");
return dialog;
}
return builder.create();
}

private boolean prepareListener() {
// init button
button1 = (Button) findViewById(R.id.button1);
button2 = (Button) findViewById(R.id.button2);
button3 = (Button) findViewById(R.id.button3);
button4 = (Button) findViewById(R.id.button4);

// init listener
listener1 = new Button.OnClickListener() {
public void onClick(View v) {
showDialog(DIALOG1);
}
};
listener2 = new Button.OnClickListener() {
public void onClick(View v) {
showDialog(DIALOG2);
}
};
listener3 = new Button.OnClickListener() {
public void onClick(View v) {
showDialog(DIALOG3);
}
};
listener4 = new Button.OnClickListener() {
public void onClick(View v) {
showDialog(DIALOG4);
}
};

// bind listener
button1.setOnClickListener(listener1);
button2.setOnClickListener(listener2);
button3.setOnClickListener(listener3);
button4.setOnClickListener(listener4);
return true;
}
}

alert_dialog_text_entry.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<!-- android:textAppearance:设置字体, 系统自带的字体 -->
<!-- android:capitalize:设置大小写;none首字母小写;words首字母大写 -->
<TextView android:id="@+id/username_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dip"
android:layout_marginRight="20dip"
android:text="用户名"
android:textAppearance="?android:attr/textAppearanceMedium"
/>
<EditText android:id="@+id/username_edit"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dip"
android:layout_marginRight="20dip"
android:capitalize="words"
android:textAppearance="?android:attr/textAppearanceMedium"
/>
<TextView android:id="@+id/password_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dip"
android:layout_marginRight="20dip"
android:text="密码"
android:textAppearance="?android:attr/textAppearanceMedium"
/>
<EditText android:id="@+id/password_edit"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dip"
android:layout_marginRight="20dip"
android:capitalize="none"
android:password="true"
android:textAppearance="?android:attr/textAppearanceMedium"
/>
</LinearLayout>


[size=x-large][color=red]去除对话框Dialog白色边框[/color][/size]
使用样式文件,在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图片,所以就是为什么我们上边的样式文件要将其背景去除掉。
前后效果对比
未设置前:
[img]http://dl.iteye.com/upload/attachment/422517/cd29a101-a5cf-38e1-bd0e-913e4182f906.jpg[/img]
设置后:
[img]http://dl.iteye.com/upload/attachment/422519/aa49baff-10bb-3a1f-8e5f-c50adb3884c8.jpg[/img]

[size=xx-small][color=red]模式对话框Dialog背景的透明度&黑暗度设置方法[/color][/size]
设置透明度:

WindowManager.LayoutParams lp=dialog.getWindow().getAttributes();
lp.alpha=1.0f;
dialog.getWindow().setAttributes(lp);

alpha在0.0f到1.0f之间。1.0完全不透明,0.0f完全透明
设置黑暗度:

dialog.setContentView(R.layout.dialog);
WindowManager.LayoutParams lp=dialog.getWindow().getAttributes();
lp.dimAmount=1.0f;
dialog.getWindow().setAttributes(lp);
dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);


Android 之 ProgressDialog
[url]http://blog.csdn.net/dadahacker/archive/2011/02/25/6208368.aspx[/url]

Android 对话框(Dialog)大全 建立你自己的对话框
[url]http://www.cnblogs.com/salam/archive/2010/11/15/1877512.html[/url]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值