`
runfeel
  • 浏览: 905420 次
文章分类
社区版块
存档分类
最新评论

AlertDialog

 
阅读更多
Android的AlertDialog详解


AlertDialog的构造方法全部是Protected的,所以不能直接通过new一个AlertDialog来创建出一个AlertDialog。

要创建一个AlertDialog,就要用到AlertDialog.Builder中的create()方法。

使用AlertDialog.Builder创建对话框需要了解以下几个方法:

setTitle :为对话框设置标题
setIcon :为对话框设置图标
setMessage:为对话框设置内容
setView : 给对话框设置自定义样式
setItems :设置对话框要显示的一个list,一般用于显示几个命令时
setMultiChoiceItems :用来设置对话框显示一系列的复选框
setNeutralButton :普通按钮

setPositiveButton :给对话框添加"Yes"按钮
setNegativeButton :对话框添加"No"按钮
create : 创建对话框
show :显示对话框
一、简单的AlertDialog

下面,创建一个简单的ALertDialog并显示它:

public class Dialog_AlertDialogDemoActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

Dialog alertDialog = new AlertDialog.Builder(this).
setTitle("对话框的标题").
setMessage("对话框的内容").
setIcon(R.drawable.ic_launcher).
create();
alertDialog.show();
}
}运行结果如下:

\" src=http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center" >

<TextView
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/user" />

<EditText
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout>

<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center" >

<TextView
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/passward" />

<EditText
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout>

</LinearLayout>
<?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="fill_parent"
android:orientation="vertical" >

<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center" >

<TextView
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/user" />

<EditText
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout>

<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center" >

<TextView
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/passward" />

<EditText
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout>

</LinearLayout>
然后在Activity里面把Login画面的布局文件添加到AlertDialog上

[java] package com.tianjf;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;

public class Dialog_AlertDialogDemoActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

// 取得自定义View
LayoutInflater layoutInflater = LayoutInflater.from(this);
View myLoginView = layoutInflater.inflate(R.layout.login, null);

Dialog alertDialog = new AlertDialog.Builder(this).
setTitle("用户登录").
setIcon(R.drawable.ic_launcher).
setView(myLoginView).
setPositiveButton("登录", new DialogInterface.OnClickListener() {

@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
}).
setNegativeButton("取消", new DialogInterface.OnClickListener() {

@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
}).
create();
alertDialog.show();
}
}

public class Dialog_AlertDialogDemoActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

// 取得自定义View
LayoutInflater layoutInflater = LayoutInflater.from(this);
View myLoginView = layoutInflater.inflate(R.layout.login, null);

Dialog alertDialog = new AlertDialog.Builder(this).
setTitle("用户登录").
setIcon(R.drawable.ic_launcher).
setView(myLoginView).
setPositiveButton("登录", new DialogInterface.OnClickListener() {

@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
}).
setNegativeButton("取消", new DialogInterface.OnClickListener() {

@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
}).
create();
alertDialog.show();
}
}运行结果如下:

\" src=

  • 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的内容:
    1. ContextmContext=getApplicationContext();
    2. Dialogdialog=newDialog(mContext);
    3. dialog.setContentView(R.layout.custom_dialog);
    4. dialog.setTitle("CustomDialog");
    5. TextViewtext=(TextView)dialog.findViewById(R.id.text);
    6. text.setText("Hello,thisisacustomdialog!");
    7. ImageViewimage=(ImageView)dialog.findViewById(R.id.image);
    8. 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)来为对话框设置展开后的布局。例如:
    1. AlertDialog.Builderbuilder;
    2. AlertDialogalertDialog;
    3. ContextmContext=getApplicationContext();
    4. LayoutInflaterinflater=(LayoutInflater)mContext.getSystemService(LAYOUT_INFLATER_SERVICE);
    5. Viewlayout=inflater.inflate(R.layout.custom_dialog,
    6. (ViewGroup)findViewById(R.id.layout_root));
    7. TextViewtext=(TextView)layout.findViewById(R.id.text);
    8. text.setText("Hello,thisisacustomdialog!");
    9. ImageViewimage=(ImageView)layout.findViewById(R.id.image);
    10. image.setImageResource(R.drawable.android);
    11. builder=newAlertDialog.Builder(mContext);
    12. builder.setView(layout);
    13. alertDialog=builder.create();
    使用AlertDialog来自定义对话框,可以利用其内置特性例如按钮、选择列表、标题、图标等。


    显示对话框

    对话框经常作为Activity的一部分来创建和显示。你通常应该从protected DialogActivity.onCreateDialog (int id)回调方法里创建对话框。当你使用这个回调函数时,Android系统会有效的设置这个Activity为每个对话框的所有者,从而自动管理每个对话框的状态并挂靠到Activity上。这样,每个对话框继承这个Activity的特定属性。比如,当一个对话框打开时,菜单键显示为这个Activity定义的选项菜单,音量键修改Activity使用的音频流

    1. 注意:如果你决定在onCreateDialog()方法之外创建一个对话框,它将不会被附着到活动上。不过,你可以通过setOwnerActivity(Activity)把它附着到一个活动上。

    当你想要显示一个对话框时,调用showDialog(int id)方法并传递一个唯一标识这个对话框的整数。

    当对话框第一次被请求时,Android从你的Activity中调用onCreateDialog(int id),你应该在这里初始化这个对话框Dialog。这个回调方法被传以和showDialog(int id)相同的ID。当你创建这个对话框后,在Activity的最后返回这个对象。

    在对话框被显示之前,Android还调用了可选的回调函数onPrepareDialog(int id, Dialog). 如果你想在每一次对话框被打开时改变它的任何属性,你可以定义这个方法。这个方法在每次打开对话框时被调用,而onCreateDialog(int) 仅在对话框第一次打开时被调用如果你不定义onPrepareDialog(),那么这个对话框将保持和上次打开时一样。这个方法也被传递以对话框的ID,和在onCreateDialog()中创建的对话框对象。(个人理解是,在本Activity里第一次show某个Dialog,则先调用onCreateDialog,得到返回的Dialog对象并挂靠在Activity,保存Dialog对象的引用,然后才显示Dialog。这样子,下次再show Dialog就不用重新创建Dialog对象,而是重用旧的)

    定义onCreateDialog(int)onPrepareDialog(int, Dialog)回调函数的最佳方法是使用一个switch 语句来检查传递进来的id 参数。每个case 应该检查一个唯一的对话框ID然后创建和定义相应的对话框。比如,想象一下一个游戏使用两个不同的对话框:一个用来指示这个游戏已经暂停而另一个来指示游戏结束。首先,为每个对话框定义一个常量:

    1. staticfinalintDIALOG_PAUSED_ID=0;
    2. staticfinalintDIALOG_GAMEOVER_ID=1;

    然后,为每一个ID用一个switch case定义这个onCreateDialog(int) 回调函数:

    1. protectedDialogonCreateDialog(intid){
    2. Dialogdialog;
    3. switch(id){
    4. caseDIALOG_PAUSED_ID:
    5. //dotheworktodefinethepauseDialog
    6. break;
    7. caseDIALOG_GAMEOVER_ID:
    8. //dotheworktodefinethegameoverDialog
    9. break;
    10. default:
    11. dialog=null;
    12. }
    13. returndialog;
    14. }

    当是时候显示其中之一的对话框时,使用对话框ID调用showDialog(int):

    1. showDialog(DIALOG_PAUSED_ID);

    消除对话框Dismissing a Dialog

    当你准备关闭对话框时,你可以通过对这个对话框调用dismiss()来消除它。如果需要,你还可以从这个Activity中调用dismissDialog(int id)方法,这实际上将为你对这个对话框调用dismiss() 方法。

    如果你想使用onCreateDialog(int id)方法来管理你对话框的状态(就如同在前面的章节讨论的那样),然后每次你的对话框消除的时候,这个对话框对象的状态将由该Activity保留。如果你决定不再需要这个对象或者清除该状态是重要的,那么你应该调用removeDialog(int id)。这将删除任何内部对象引用而且如果这个对话框正在显示,它将被消除。

    使用消除侦听器Using dismiss listeners

    如果你希望你的应用程序在一个对话框消亡的时候执行一些流程,那么你应该附着一个on-dismiss侦听器到对话框上。

    1. @Override
    2. protectedvoidonPrepareDialog(intid,Dialogdialog){
    3. switch(id){
    4. casePROGRESS_DIALOG:
    5. dialog.setOnDismissListener(newDialogInterface.OnDismissListener(){
    6. @Override
    7. publicvoidonDismiss(DialogInterfacedialog){
    8. Toast.makeText(getApplicationContext(),
    9. "dismisslistener!",
    10. Toast.LENGTH_SHORT)
    11. .show();
    12. }
    13. });
    14. }
    15. }

    然而, 请注意对话框也可以被“取消”。这是一个表明对话框被用户显示取消的特殊情况。这将在用户按“返回”按钮时发生,或者这个对话框显示的调用cancel()(也许通过对话框上的一个“取消”按钮)。当一个对话框被取消时,这个OnDismissListener 依然会被通知到,但是如果你希望在对话框被显示取消时被通知到(而不是通常的消除方式),那么你应该通过setOnCancelListener()注册一个DialogInterface.OnCancelListener

    目前个人学习发现,一般情况下,调用dialog.cancel()就会触发onCancelLister。而点击AlertDialog的NegativeButton (Cancel/No)是不会触发的。对于setOnCancelListener()要注意的是,这里有两个setOnCancelListener(),但返回值不同:

    1. //AlertDialog.Builder调用的
    2. publicAlertDialog.BuildersetOnCancelListener(DialogInterface.OnCancelListeneronCancelListener)
    3. //Dialog调用的
    4. publicvoidsetOnCancelListener(DialogInterface.OnCancelListenerlistener)

    警告对话框AlertDialog的使用

    为了创建一个警告对话框,使用AlertDialog.Builder子类。通过AlertDialog.Builder(Context)获取一个构造器然后使用这个类的公共方法来定义警告对话框的所有属性。当得到构造器后,通过create().方法来获取警告对话框对象。有时我是不调用create()的,而是在设置好了后直接调用show()显示AlertDialog。

    Dialog_buttonDialog_buttonDialog_button

    增加按钮Adding buttons

    这就是我一开始很想知道的究竟如何添加Yes/No,Ok/Cancel这样的按钮。原来是通过setPositiveButton(...)响应Yes/Ok的点击,setNeutralButton(...)响应中立行为的点击,setNegativeButton(...)响应No/Cancel的点击。注意,只能各自设置一个按钮来响应点击事件。

    1. AlertDialog.Builderbuilder=newAlertDialog.Builder(this);
    2. builder.setMessage("Areyousureyouwanttoexit?")
    3. .setCancelable(false)
    4. .setPositiveButton("Yes",newDialogInterface.OnClickListener(){
    5. publicvoidonClick(DialogInterfacedialog,intid){
    6. MyActivity.this.finish();
    7. }
    8. })
    9. .setNegativeButton("No",newDialogInterface.OnClickListener(){
    10. publicvoidonClick(DialogInterfacedialog,intid){
    11. dialog.cancel();
    12. }
    13. });
    14. AlertDialogalert=builder.create();

    首先,为这个对话框添加一个消息setMessage(CharSequence)。然后,开始函数链并设置该对话框为不能取消not cancelable (因此用户不能使用返回按钮关闭这个对话框)。对每个按钮,使用任一set...Button() 方法,比如setPositiveButton(),该方法接受按钮名称以及一个定义用户选中按钮后所采取动作的DialogInterface.OnClickListener

    增加一个列表Adding a list
    1. finalCharSequence[]items={"Red","Green","Blue"};
    2. AlertDialog.Builderbuilder=newAlertDialog.Builder(this);
    3. builder.setTitle("Pickacolor");
    4. builder.setItems(items,newDialogInterface.OnClickListener(){
    5. publicvoidonClick(DialogInterfacedialog,intitem){
    6. Toast.makeText(getApplicationContext(),items[item],Toast.LENGTH_SHORT).show();
    7. }
    8. });
    9. AlertDialogalert=builder.create();

    首先,用setTitle(CharSequence)方法给对话框添加一个标题。然后,添加用setItems()添加一个可选项列表,该列表接受一组显示的items和一个DialogInterface.OnClickListener 来定义用户选中按钮后所采取动作。

    增加复选框和单选按钮

    要在对话框里创建一个多选项列表(checkboxes)或者单选项(radio buttons),可分别调用setMultiChoiceItems()setSingleChoiceItems()方法。如果你在onCreateDialog()回调函数中创建这些可选列表,Android会帮你管理列表状态。只要这个活动是激活的,对话框会记住之前选中的items,但如果用户退出这个活动,用户选择将丢失。

    注意: 为了在用户离开或暂停这个活动的时候能够保存选择,你必须通过活动生命期Activity Lifecycle来恰当的保存和恢复设置。为了永久保存选项,即使活动进程被完全终止,你需要使用数据存储Data Storage技术。

    1. finalCharSequence[]items={"Red","Green","Blue"};
    2. AlertDialog.Builderbuilder=newAlertDialog.Builder(this);
    3. builder.setTitle("Pickacolor");
    4. builder.setSingleChoiceItems(items,-1,newDialogInterface.OnClickListener(){
    5. publicvoidonClick(DialogInterfacedialog,intitem){
    6. Toast.makeText(getApplicationContext(),items[item],Toast.LENGTH_SHORT).show();
    7. }
    8. });
    9. AlertDialogalert=builder.create();

    setSingleChoiceItems()的第二个参数是一个checkedItem整型数值,指示了基于0的缺省选择项的位置。“-1”代表不会有默认选择项。

    进度对话框Progress Dialog的使用

    ProgressDialogAlertDialog类的一个扩展,可以为一个未定义进度的任务显示一个旋转轮形状的进度动画,或者为一个指定进度的任务显示一个进度条。

    可以简单地通过调用ProgressDialog.show()方法来显示一个进度对话框,而通过onCreateDialog(int)回调管理这个对话框是可选的,如下所示:

    1. ProgressDialog.show(this,//context
    2. "",//title
    3. "Loading.Pleasewait...",//message
    4. true);//进度是否是不确定的,这只和创建进度条有关


    分享到:
    评论

    相关推荐

    Magicbox
    Global site tag (gtag.js) - Google Analytics