翻译Dev Guide 之 创建Dialog

创建Dialog
一个Dialog通常是一个出现在目前Activity前方的小窗口。这个Dialog将接受用户的交互而底下的Activity将会失去焦点。Dialog通常用于需要打扰用户的通知,执行与应用程序进展直接相关的短暂任务(比如一个进度条或者登录提示)。
Dialog类是创建Dialog的基础类。但是,通常你不应该直接实例化Dialog类,而是使用以下子类之一:
 
    1.AlertDialog,可以管理0,1,2或者3个Button,和/或一个可以包含checkbox/radiobutton的可选项列表。AlertDialog可以构造大部分的DialogUI,并且是推荐的Dialog类型。
      2.ProgressDialog,展示了一个进度轮或者进度条,由于是AlertDialog的扩展,它也支持Button。
      3.DatePickerDialog,允许用户选择一个日期。
      4.TimePickerDialog,允许用户选择一个时间。
如果你希望定制自己的Dialog,你可以继承Dialog类或者以上的任意子类,然后重新定义布局。

显示一个Dialog

一个Dialog总是作为一个Activity的一部分来创建和显示。通常你应该在你的Activity的onCreateDialog(int)回调函数内创建Dialog。当你使用这个回调的时候,Android系统自动管理每个Dialog的状态并把它们挂到Activity,有效地让它成为每个Dialog的所有人。这样,每个Dialog从Acitivity继承了一些属性。比如,当一个Dialog打开的时候,Menu键会打开为这个Activity定义的optionsmenu,而Volume键会调整Activity使用的音频流。
注意:如果你决定在onCreateDialog()外创建一个Dialog,那么它对Acitivity不可见,但是你可以用setOwnerActivity(Activity)将它附着到Acitvity上。
当你想显示一个Dialog时,调用showDialog(int)并传递进一个唯一标识你想显示的Dialog的整数。
当一个Dialog第一次被请求时,Android从你的Activity调用onCreateDialog(int),在这个方法里你应该实例化你的Dialog。传入这个回调函数的ID跟传入showDialog(int)的是同一个。创建好Dialog后,在函数的末尾返回此对象。
在显示Dialog之前,Android还会调用可选的回调函数onPrepareDialog(int,Dialog)。如果你希望在每次打开Dialog的时候都修改它的属性,那么就定义这个函数。每次打开Dialog的时候这个函数会被调用,而onCreateDialog(int)只会在第一次打开Dialog的时候调用。如果你不定义onPrepareDialog(int,Dialog),那么Dialog将会和它上次打开时一样。Dialog的ID与你在onCreateDialog()里创建的Dialog将一起被传给这个函数。
调用showDialog(intid)时,会用id调用onCreateDialog(int)或者onPrepareDialog(int)进行创建或者修改,然后再显示出来。
//定义onCreateDialog(int)和onPrepareDialog(int, Dialog)的最佳方式,是用一个switch声明来检查传入的ID,每个case值检查一个唯一的Dialog ID,然后创建和定义各自的Dialog。比如,想象一个游戏使用了两个Dialog:一个说明游戏暂停,另一个说明游戏结束。首先,为每个Dialog定义一个整型ID:
    static final int DIALOG_PAUSED_ID = 0;
    static final int DIALOG_GAMEOVER_ID = 1;
//然后用一个包含了所有ID case的switch来定义onCreateDialog(int)回调:
    protected Dialog onCreateDialog(int id){
        Dialog dialog;
        switch (id) {
        case DIALOG_PAUSED_ID:
            // do the work to define the pause Dialog
            break;
        case DIALOG_PGAMEOVER_ID:
            // do the work to define the game over Dialog
            break;
        default:
            dialog = null;
        }
        return dialog;
    }
//要显示dialog的时候,用dialog的id调用showDialog(int):
    showDialog(DIALOG_PAUSED_ID);


解散一个Dialog

当你准备关闭你的dialog的时候,你可以调用Dialog对象的的dismiss()方法来解散它。必要的话,也可以从Activity上调用dismissDialog(int),它会为你有效地调用Dialog的dismiss()。
如果你用onCreateDialog(int)管理你的Dialog状态(如上节讨论),那么每次你的Dialog被解散的时候,Activity会保存它的状态。如果你决定你不再需要这个对象或者清理状态很重要,那么你需要调用removeDialog(int)。它会清除任何对此对象的内在关联,如果此dialog正在显示中的话,还会关闭它。
使用解散listener
如果你希望你的程序在解散Dialog的时候执行一些代码,那么你需要在你的dialog上附着on-dismisslistener。
首先定义DialogInterface.OnDismissListener接口。这个接口只有一个方法,onDismiss(DialogInterface),当dialog解散的时候会被调用。然后把你的OnDIsmissListener实现传递到setOnDismissListener()即可。
但是,注意Dialog也可以被cancel。这特指用户明确cancel这个dialog的情况。当用户按下back键来关闭dialog,或者Dialog显示调用cancel()(也许从dialog上的cancel按钮)时会发生。当一个dialog被cancel的时候,会通知OnDismissListener,但是如果你希望被告知dialog是显示调用cancel()而不是普通的dismiss,那么你需要注册一个DialogInterface.onCancelListener或者setOncancelListener()。


创建一个AlertDialog

AlertDialog是Dialog类的扩展,可以构造大部分的DialogUI,并且是推荐的Dialog类型。当dialog用到以下特性之一时你就应使用AlertDialg:
 
    一个title。
      一个文本消息。
      一个,两个或者三个Button。
      一个可选列表(包括可选的checkbox和radiobut)。
注意在AlertDialog文本消息和列表不能同时显示。
为了创建一个AlertDialog,使用AlertDialog.Builder子类。用AlertDialog.Builder(Context)获得一个Builder,然后使用这个类的公共方法定义AlertDialog的所有属性。完成后就可通过create()取回AlertDialog对象。
接下来的内容展示了如何用AlertDialog.Builder类来定义AlertDialog的各种属性。

添加Button

为了创建有side-by-side的Button的AlertDialog,使用set...Button()函数:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setMessage("Are you sure you want to exit?")
                 .setCancelable(false)
                 .setPositiveButton("Yse", new DialogInterface.OnClickListener() {
                   
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        MyActivity.finish();
                       
                    }
                })
                .setNegativeButton("no", new DialogInterface.OnClickListener() {
                   
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.cancel();
                       
                    }
                });
        AlertDialog alert = builder.create();
首先用setMessage(CharSequence)为dialog添加一个message,然后开始函数链,用setCancelable(boolean)设置了dialog不能被cancel(用户不能用back键关闭dialog),为每个Button用一个set...Button(),接受Button的名字和DialogInterface.OnClickListener。
注意:每种Button只能添加一个,总共有三种为positive,neutral和negative。


添加一个列表

创建可选列表要用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() {
           
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Toast.makeText(getApplicationContext(), items[which], Toast.LENGTH_SHORT).show();
            }
        });
        AlertDialog alert = builder.create();
首先,用setTitle(CharSequence)给Dialog设置一个标题,然后用setItem()添加一个可选列表,它接收一个选项数组用于显示和一个DialogInterface.OnClickListener用于监听点击选项。


添加checkbox和radiobutton

向Dialog里添加一个有复选选项checkbox或者单选选项radiobutton的列表,各自要用setMultiChoiceItems()和setSingleChoiceItems()函数。如果你在onCreateDialog()回调函数里使用了这些,Android会替你管理列表的状态。只要Activity还活跃,dialog就会记住上次选择的选项,但是如果用户退出Activity,选择就忘记了。
注意:为了在用户离开或者暂停Activity时保存选择,你必须在整个Activity生命周期中进行恰当的存储和恢复。为了永久地保存选择,即使Activity的进程完全停止,你需要使用一种数据存储技术( DataStorage)。
要创建一个选项可单选列表,代码和上面一样,只需要把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() {
           
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Toast.makeText(getApplicationContext(), items[which], Toast.LENGTH_SHORT).show();
            }
        });
        AlertDialog alert = builder.create();
setSingleChoiceItems()中第二个参数是标记选项的一个整数,说明了这个零基列表默认的选项位置,选择“-1”表示默认无选项被选中。


创建ProgressDialog

ProgressDialog是Dialog的扩展,可以为一个有未定义进度的任务以 一个旋转的轮子形式显示进度动画,或者为一个有已定义进度的任务显示进度条,还可以提供按钮用于比如退出一个下载。
打开一个ProgressDialog只要调用ProgressDialog.show()就可以了。比如:
    ProgressDialog dialog = ProgressDialog.show(MyActivity.this, "", "Loading, Please wait...", true);
第一个参数是应用程序的context,第二个是dialog的标题,第三个是message,第四个表示进度是否不定(只跟进度条有关,下节讨论)。
默认的ProgressDialog类型就是旋转的轮子,如果你想要创建按粒度显示进度的进度条,需要更多代码如下。

显示进度条



用动态进度条显示进度的步骤:
   1.用类构造器ProgressDialog(Context)初始化ProgessDialog。
   2.用setProgressStyle(int)把进度类型设置为“STYLE_HORIZONTAL”,并设置其他属性,如message等。
   3.当你准备显示Dialog时,调用show(),或者返回来自onCreateDialog(int)回调的ProgressDialog。
   4.你可以用目前完成的百分比调用setProgress(int),或者用加到目前完成百分比的增量值调用incrementProgressBy(int),来增加显示在进度条上的进度量。
注意设置进度一定要在show()之后,否则设置无效。
比如你的设置可以是这样:
ProgressDialog progressDialog = new ProgressDialog(mContext);
    progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
    progressDialog.setMessage("Loading...");
    progressDialog.setCancelable(false);

设置很简单。创建一个ProgressDialog的大部分代码实际上都包含在更新程序中了。你也许会发现有必要在应用程序中创建一个次线程去完成这个工作,然后有一个Handler对象把进度回报给Activity的UI线程。


创建自定义Dialog

如果你想自主设计一个Dialog,你可以用layout和widget元素为Dialog窗口创建一个你自己的布局。定义完布局之后,把根View对象或者布局资源ID传给setContentView(View)。步骤:
   1.创建XML布局文件,如custom_layout.xml
<LinearLayout xmlns:android="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"

                      >
        
        
<ImageView android:id="@+id/image"

                      android:layout_width="wrap_content"

                 
      android:layout_height="fill_parent"

                 
      android:layout_marginRight="10dp"

                />

               <TextView android:id="@+id/text"

                      
android:layout_width="wrap_content"

                    
  android:layout_height="fill_parent"

                      
 android:textColor="#FFF"

               />
        
</LinearLayout>

这个XML在一个LinearLayout里定义了一个ImageView和一个TextView。

    2.把上面的布局设置为dialog的内容布局,定义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后,将layout资源ID传给setContentView(int)把你自己的layout设为dialog的内容视图,然后Dialog有了一个已定义的布局,可以用findViewById(int)来捕捉View对象并修改其内容了。

注意,经过测试发现,按如上代码直接对自定义Dialog使用findViewById()是不能获取控件的,正确的做法是:
    先获取LayoutInflater,用其inflate(int, ViewGroup)方法对自定义布局进行缩放,得到一个View。
    然后用自己的Dialog的setContentView(View)将这个View设置为Dialog的布局。
    在通过这个View的对象名来调用findViewById()来获取控件。 但是设置布局文件和设置其控件并无严格的顺序,为了便于记忆和理解,尽量先设置布局文件,在设置其控件。     3.搞定。现在你可以显示你的Dialog了。 一个用Dialog基础类做的Dialog必须有个标题。如果你不调用setTitle(),那标题位置就是空的,但仍然可见。如果你根本不想要标题,那么你应该用AlertDialog类创建自己的Dialog。但是,由于AlertDialog用AlertDialog.Builder创建是最简单的,你接触不到上面用的setContentView(View),而必须用setView(View)。这个函数接受一个View对象,所以你需要膨胀布局XML的根View对象。 要膨胀XML布局,用getLayoutInflater()或者getSystemService()获取LayoutInflater,然后调用inflate(int, ViewGroup),第一个参数是布局资源ID,第二个是根View的ID。然后你就可以被膨胀的layout去发现View对象及设置它们的属性了。然后实例化AlertDialog.Builder,并用setView()把被膨胀了的layout设置到Dialog中。 下面有个在AlertDialog中创建自定义Dialog的示例:
AlertDialog.Builder builder;

        AlertDialog alertDialog;

        

        Context mContext = getApplicationContext();

        LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(LAYOUT_INFLATER_SERVICE);

        View layout = inflater.inflate(R.id.custom_dialog, 

                        (ViewGroup)layout.findViewById(R.id.layout_root));

        

        TextView text = (TextView)findViewById(R.id.text);

//同样的,这里获取TextView应该用(TextView)layout.findViewById(R.id.text);

        text.setText("Hello, this is a custom dialog!");

        ImageView image = (ImageView)findViewById(R.id.image);

        image.setImageResource(R.drawable.android);

        

        builder = new AlertDialog.Builder(mContext);

        builder.setView(layout);

        alertDialog = builder.create();

为你的布局使用AlertDialog可以利用AlertDialog的内在特性,比如被管理的按钮,可选列表,标题,图标等等。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值