Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Dialog的使用與總結

Dialog的使用與總結

編輯:關於Android編程

Dialog 使用總結

DialogAndroid中對話框相關的類,起到相關提示的作用。

Dialog在Android 中主要分為以下幾類:

AlertDialog :警告對話框(提示對話框) ProgressDialog:進度對話框 DatePickerDialog:日期選擇對話框 TimerPickerDialog: 時間選擇對話框 自定義對話框

下面將按照如上所分類,進行一一介紹。

AlertDialog

AlertDialog 的簡單使用

AlertDialog 繼承 Dialog,該對象對於常用的一些對話框進行了封裝。

需要注意的是AlertDialog存在兩種實現並對應的存在於兩個不同的包,

Android 原生包android.app.AlertDialog。該包中的AlertDialog並沒有對不同版本的系統進行適配。在不同的手機系統上會顯示不同的樣式。(不推薦)。 v7包android.support.v7.app.AlertDialog。該包中的AlertDialog是根據google 推出的Material Desgin進行設計的,並對低版本的系統進行了適配。支持系統版本到7(Android 2.1 )以上。(推薦)

下面都將使用v7版本的AlertDialog

AlertDialog的使用分為以下幾步:

創建AlertDialog.Builder對象,該對象能創建AlertDialog。 調用Builder對象的方法設置圖標、標題、內容、按鈕等。
setTitle():為對話框設置標題 setIcon ():設置圖標 setMessage ():設置要顯示的信息 setPositiveButton ():設置確定按鈕 setNegativeButton (): 設置取消按鈕 setNeutralButton ():設置中立按鈕 調用Builder對象的create()方法創建AlertDialog對話框。 調用AlertDialogshow()方法來顯示對話框 調用AlertDialogdimiss()方法銷毀對話框。

下面就根據上面的步驟,來創建AlertDialog方法。


    public void dialog1(View view){
        // 簡單的AlertDialog

        // 1 . 創建AlertDialog 對象
        //          注意 Dialog 的Builder的創建雖然傳入的是Context,其實是多態,此處必須傳入Activity對象
        AlertDialog.Builder builder = new AlertDialog.Builder(this);

        // 2. 通過builder 設置一些常用的屬性
        //   設置圖標
        builder.setIcon(R.mipmap.ic_launcher);
        // 設置標題
        builder.setTitle("提示");

        //設置提示消息
        builder.setMessage("這是一個基礎的AlertDialog");

        builder.setPositiveButton("確定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                //點擊確定按鈕之後的回調
                Toast.makeText(AlertDialogActivity.this, "確定", Toast.LENGTH_SHORT).show();
            }
        });

        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                //點擊取消按鈕之後的回調
            }
        });

        builder.setNeutralButton("中間", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                //點擊中間的按鈕的回調
            }
        });


        //3 .通過Builder  的 create方法創建AlertDialog;

        AlertDialog dialog = builder.create();


        // 4 . 顯示對話框

        dialog.show();

    }

看一下效果

這裡寫圖片描述

有以下幾點需要注意:<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxjb2RlPkFsZXJ0RGlhbG9nPC9jb2RlPrrNPGNvZGU+QnVpbGRlcjwvY29kZT61vMjrtcS2vMrHPGNvZGU+YW5kcm9pZC5zdXBwb3J0LnY3LmFwcC5BbGVydERpYWxvZzwvY29kZT6hoyDIt7aoo6zIoc/7us3W0LzkyP249rC0xaW1xL3Tv9q72LX3o6y147v3yrHErMjPtry199PDwcs8Y29kZT5kaW1pc3MoKTwvY29kZT63vbeoo6zL+dLUztLDx87e0OjK1rav0v6y2Mv7oaMg0ruw49TayrnTw9bQo6yyu7vhyrnTw9bQvOTEx7j2sLTFpaGjtrzKx8G9uPawtMWl1+O5u6O6yKHP+7rNyLe2qKOsyLe2qNTa09KjrMihz/vU2tfzoaO31rHwttTTpsG9uPa84Mz9PGNvZGU+c2V0UG9zaXRpdmVCdXR0b248L2NvZGU+us08Y29kZT5zZXROZWdhdGl2ZUJ1dHRvbjwvY29kZT6ho9OizsS1pbTK0uLOqrv9vKu1xLrNz/u8q7XEoaMgtLS9qDxjb2RlPkRpYWxvZzwvY29kZT7L5Mi70OjSqrXEysc8Y29kZT5Db250ZXh0PC9jb2RlPiy1q7HY0Ou0q8jrPGNvZGU+QWN0aXZpdHk8L2NvZGU+ttTP86GjDQo8cD7I57n7uduy7NfQz7i1xLvht6LP1jxjb2RlPmJ1aWxkZXI8L2NvZGU+tcQ8Y29kZT5zZXhYWFg8L2NvZGU+t723qKOst7W72LXEyNTIu8rHPGNvZGU+QnVpbGRlcjwvY29kZT621M/zoaPEx8O0ztLDx7/J0tTQ3rjEtPrC69auuvPI58/Co7o8L3A+DQo8cHJlIGNsYXNzPQ=="brush:java;"> AlertDialog dialog = new AlertDialog.Builder(this) .setIcon(R.mipmap.ic_launcher) .setTitle("提示") .setMessage("這是一個基礎的AlertDialog") .setPositiveButton("確定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { //點擊確定按鈕之後的回調 Toast.makeText(AlertDialogActivity.this, "確定", Toast.LENGTH_SHORT).show(); } }) .setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { //點擊取消按鈕之後的回調 } }) .setNeutralButton("中間", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { //點擊中間的按鈕的回調 } }).create();

類似一條鏈式的創建Dialog對象。

繼承於Dialog的一些特性

因為AlertDialog繼承Dialog,所以他擁有Dialog的特性。(該特性對於所有的對話框都適用)

其中幾個常用的方法:

setCancelable(boolean flag):當點擊返回鍵的時候,Dialog是否消失。 true 表示點擊返回鍵提示框消失。 false表示不消失,即點擊返回無效果。 setCanceledOnTouchOutside (boolean cancel) 點擊對話框以外的區域時,對話框是否消失。true 表示點擊以外的區域消失,false表示不消失。

        // 點擊返回不會取消對話框
        dialog.setCancelable(false);

        // 觸摸對話框以外的區域不會消失
        dialog.setCanceledOnTouchOutside(false);

注意:該方法是Dialog的方法,不是Builder中的方法。

具有單選功能的對話框

實現單選功能對話框有兩種實現方式,通過兩個方法setItemssetSingleChoiceItems

setItems:通過該方法實現對話框,無需點擊確定,直接點擊條目之後立即消失,同時調用相應的回調。 setSingleChoiceItems:普通的單選效果,帶有圓圈,點擊確定之後隱藏。

首先看一下兩個的效果圖:

這裡寫圖片描述
- setItems()方法實現單選

final String[] sex = {"男","女"};

        AlertDialog dialog = new AlertDialog.Builder(this)

                .setItems(sex, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        // which 表示的 點擊的索引。
                        Toast.makeText(AlertDialogActivity.this, sex[which], Toast.LENGTH_SHORT).show();
                    }
                }).create();

        dialog.show();

setItems(CharSequence[] items, final OnClickListener listener): 第一個參數為顯示不同數據的數組。第二個方法為選擇之後的回調。

setSingleChoiceItems實現:

    public void choice_single(View view){

        final String[] sex = {"男","女"};

        AlertDialog dialog = new AlertDialog.Builder(this)
                .setSingleChoiceItems(sex, 0,new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        // which 表示的 點擊的索引。
                        Toast.makeText(AlertDialogActivity.this, sex[which], Toast.LENGTH_SHORT).show();

                        //保存狀態
                    }
                })
                .setPositiveButton("確定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        // 確定操作

                        //通過在上一個onClick方法中的回調的記錄,進行對應操作。
                    }
                })
                .create();

        dialog.show();

    }

setSingleChoiceItems(CharSequence[] items, int checkedItem,final OnClickListener listener): 第一個參數表示數據數組,第二個參數表示默認選中第幾條,第三個參數為借口回調。

兩種方式實現的比較:
setItems方式實現無法修改,只能選擇一次,選中之後對話框就會消失。 setSingleChoiceItems,可以設置默認的選中條目,多次選擇,選中之後不會消失,直到點擊確定等隱藏對話框的操作。 兩者選中事件的回調相同,都是在他們的參數中的回調對象進行操作。

實現多選對話框

AlertDialog.Builder中存在方法setMultiChoiceItems(CharSequence[] items, boolean[] checkedItems, DialogInterface.OnMultiChoiceClickListener listener)設置多選對話框。

CharSequence[] items:可選的條目的數組數據。 boolean[] checkedItems:默認顯示的狀態,與條目一一對象,false表示不選中,true表示默認選中。 DialogInterface.OnMultiChoiceClickListener listener:條目選擇產生變化之後的回調

看一下效果:
這裡寫圖片描述

具體代碼



        final String[] like = {"足球","籃球","乒乓球","排球"};
        final boolean[] check = {false,false,true,true};

        AlertDialog dialog = new AlertDialog.Builder(this)
                .setMultiChoiceItems(like, check, new DialogInterface.OnMultiChoiceClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which, boolean isChecked) {
                        // which 數據變化的索引   isChecked 表示變化的結果

                        // 根據變化修改數據
                        check[which] = isChecked;
                    }
                })
                .setPositiveButton("確定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        // 確定操作

                        //根據check 中的true 和 flase 進行處理不同結果。

                        String select = "";
                        for(int i = 0;i
setMultiChoiceItems中的OnMultiChoiceClickListener(),數據變化時回調此方法,我們需要在此方法中保存修改的數據。

ProgressDialog 進度對話框

ProgressDialog 也是繼承於Dialog,但其擴展了緩沖加載提示的功能。

總共分為兩種樣式,一種是圓形轉圈的加載,一種是水平進度條(帶有加載進度)的效果。

看一下效果:

這裡寫圖片描述

圓形加載對話框

看一下demo

  /**
     * 圓形加載對話框
     * @param view
     */
    public void progress_circle(View view){
        final ProgressDialog pd  = new ProgressDialog(this);
        // 進度條為水平旋轉
        pd.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        // 設置點擊返回不能取消
        pd.setCancelable(false);
        //設置觸摸對話框以外的區域不會消失
        pd.setCanceledOnTouchOutside(false);
        // 設置提示的title的圖標,默認是沒有的,如果沒有設置title的話只設置Icon是不會顯示圖標的
        pd.setIcon(R.mipmap.ic_launcher);
        // 設置標題
        pd.setTitle("提示");

        pd.setOnDismissListener(new DialogInterface.OnDismissListener() {
            @Override
            public void onDismiss(DialogInterface dialog) {

                // dimiss的監聽
            }
        });

        pd.setOnCancelListener(new DialogInterface.OnCancelListener() {
            @Override
            public void onCancel(DialogInterface dialog) {
                //cancel
            }
        });

        pd.setMessage("這是一個圓形進度條");
        pd.show();

        new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    Thread.sleep(5000);
                    //pd.cancel();
                    pd.dismiss();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        }).start();

    }
直接 newProgressDialog,並沒有創建什麼Builder類。 通過設置setProgressStyleProgressDialog.STYLE_SPINNER,使其顯示圓形加載效果。 pd.dismiss()pd.cancel()方法都能夠隱藏加載對話框。
cancel()表示隱藏對話框,對話框並不會被銷毀。會回調setOnCancelListener. dismiss():銷毀對話框,回調setOnDismissListener

推薦使用dismiss()方法。因為,如果調用了cancel,在activity結束時,仍要手動調用dismiss。不然,dialog如果沒有銷毀,則會導致內存溢出。

水平加載對話框

  /**
     * 水平加載進度對話框
     * @param view
     */
    public void progress_horizontal(View view){
        final ProgressDialog pd = new ProgressDialog(this);
        // 設置水平進度條
        pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        // 設置點擊返回不能取消
        pd.setCancelable(false);
        //設置觸摸對話框以外的區域不會消失
        pd.setCanceledOnTouchOutside(false);
        // 設置提示的title的圖標,默認是沒有的,如果沒有設置title的話只設置Icon是不會顯示圖標的
        pd.setIcon(R.mipmap.ic_launcher);
        // 設置標題
        pd.setTitle("提示");

        // 默認為100
        pd.setMax(100);

        pd.setMessage("這是一個水平進度條");
        pd.show();

        new Thread(new Runnable() {

            @Override
            public void run() {
                int i = 0;
                while (i < 100) {
                    try {
                        Thread.sleep(200);
                        // 每次增加 1%
                        pd.incrementProgressBy(1);
                        i++;

                    } catch (Exception e) {
                    }
                }
                pd.dismiss();

            }
        }).start();

    }

設置一個線程,通過線程沒個200ms使進度值+1,最後銷毀dialog

設置樣式:setProgressStyleProgressDialog.STYLE_HORIZONTAL 設置總的進度:pd.setMax(),整形,默認為100。 動態改變進度:pd.incrementProgressBy(1);,改變當前進度值,傳入的參數為遞增量。

DataPickerDialog 日期選擇對話框

Android 提供的原生控件,使用起來比較簡單,但因為其沒有對不同系統做適配,所以在不同系統上顯示可能不同。只做了解即可。一般都是自定義日期對話框。

效果
這裡寫圖片描述

注意:該效果是在Android5.0和以上系統上顯示的效果。具體適配會在後面提到。

使用方式

/**
     * 日期選擇器
     * @param view
     */
    public void dialog_date(View view){

        // 年,天,時,分都是從 1 開始  月從1 開始

        // 獲取系統當前時間
        Calendar instance = Calendar.getInstance();
        int year = instance.get(Calendar.YEAR);
        int month = instance.get(Calendar.MONTH); // 該方法month 從0 開始
        int day = instance.get(Calendar.DAY_OF_MONTH);


        // 構造dialog
        DatePickerDialog dialog = new DatePickerDialog(this,new DatePickerDialog.OnDateSetListener() {
            @Override
            public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {

                // 獲取到的month 需要+1 獲取正確的月份
                Toast.makeText(AlertDialogActivity.this, year+"-"+monthOfYear+"-"+dayOfMonth, Toast.LENGTH_SHORT).show();
            }
        },year,month,day);



        dialog.show();

    }

通過Calendar獲取系統當前時間,並通過DatePickerDialog的構造方法傳入系統當前時間和相應的數據回調。最後在顯示。

DatePickerDialog()構造方法有5個參數:
- 當前Activity
- onDateSetListener():數據的回調,在點擊確定是將數據作為參數回調onDateSet方法。
- year, 年
- month,注意+1和-1
- day,天

有以下幾點注意:

在JAVA的時間中,無論是當前的Calendar還是DataPicker,他們的年,天,時,分都是從0開始的,也就是直接獲取值顯示即可。而月是從0開始的,即我們需要對數據進行+1或-1操作。
如果日期是2016-6-15,則傳入的參數為,2016,5,15 如果onDataSet回調的日期是2016,5,15。則在顯示時需要對月份+1 ,即2016,6(5+1),15 顏色的設置:可以看到起彈出的大部分是粉紅色,我們可以自定義粉紅色區域的顏色。該顏色獲取的是我們對應用設置的主題中的

TimePicker 時間選擇器

該控件的使用和DatePickerDialog的使用基本類似。

看一下效果
這裡寫圖片描述

注意:該效果是在Android5.0和以上系統上顯示的效果。具體適配會在後面提到。

 /**
     * 時間選擇器
     * @param view
     */
    public void dialog_time(View view){

        // 獲取系統時間
        Calendar instance = Calendar.getInstance();
        int hour = instance.get(Calendar.HOUR_OF_DAY);
        int minute = instance.get(Calendar.MINUTE);


        // 時間對話框
        TimePickerDialog dialog = new TimePickerDialog(this, new TimePickerDialog.OnTimeSetListener() {
            @Override
            public void onTimeSet(TimePicker view, int hourOfDay, int minute) {

                Toast.makeText(AlertDialogActivity.this, hourOfDay+"-"+minute, Toast.LENGTH_SHORT).show();
            }
        },hour,minute,true);

        //顯示
        dialog.show();
    }

TimePickerDialog的有5個參數
- 當前Activity的對象
- onTimeSetListener,數據回調。
- hour:小時
- minute:分
- is24hourView: false:不使用24小時制。true:使用24小時表示。

自定義Dialog

在平常的項目中,因為系統提供的dialog無法很好的適配不同的版本(樣式不同),通常自定義Dialog實現相應功能。

實現的步驟:

編寫自定義的布局 自定義類繼承Dialog並實現構造方法。 設置dialog的主題。 加載自定義布局 使用setContentView設置到dialog中。 查找相應控件並編寫邏輯。

看一下效果

這裡寫圖片描述

編寫自定義布局dialog_simple.xml



    


    

        


    


很多需求模仿IOS 實現外框是一個圓角矩形的形式。Dialog並沒有提供對應的方法,我們需要從自定義布局上,設置它的背景為圓角矩形。

圓角矩形shape資源shape_dialog_psd_bg.xml



    

    

    

下面就是編寫CustomDialog

/**
 * 簡單的對話框
 * Created by MH on 2016/6/15.
 */
public class SimpleDialog extends Dialog implements View.OnClickListener {


    public SimpleDialog(Context context) {

        // 注意,在此處設置樣式
        super(context,R.style.CustomDialog);

        // 設置我們的布局到dialog中
        setContentView(R.layout.dialog_simple);

        // 初始化布局
        initView();
    }

    private void initView() {
        findViewById(R.id.dialog_simple_cancel).setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {

            case R.id.dialog_simple_cancel:
                // 對應的點擊事件
                this.dismiss();
                break;
        }
    }
}

在如上類中,關鍵的幾步如下:

重寫構造方法,我們選擇只有一個參數的。 構造方法調用父類構造方法並傳入了dialog的樣式。 setContentView()設置自定義布局到dialog中。 查找控件並編寫相應的邏輯

其中需要注意的一點為設置樣式,該樣式設置的目的是為了統一不同系統版本下顯示的樣式,如果不設置,在低於Android5。0的系統下會爆炸。。。

在此定義的樣式一般為

自定義Dialog大概就這麼多,復雜的無非就是界面復雜點,邏輯復雜點那麼多。

Dialog 設置動畫

看一下效果圖

這裡寫圖片描述

下面就開始實現,定義動畫需要通過xml文件來編寫動畫

dialog_anim_enter.xml 進入的動畫



    

    


dialog_anim_exit.xml 離開動畫

    

    

如果對動畫不是太熟悉的,可以看我之前的博客Android動畫之視圖動畫和屬性動畫

在這裡需要注意,雖然是相對父布局,但仍然是我們顯示的dialog的左上角為0坐標開始偏移的,效果是相對於本身的動畫。我猜測應該是dialog外層包裹了另一個和他一樣大小的布局。

編寫動畫的樣式

通過dialog.getWindow().setWindowAnim(int resId)方法設置動畫

/**
     * dialog設置動畫
     */
    public void dialog_anim(View view){

        SimpleDialog dialog = new SimpleDialog(this);
        // 設置動畫
        dialog.getWindow().setWindowAnimations(R.style.DialogAnim);

        dialog.show();
    }

該動畫的設置方法對所有的dialog都適用,即之前系統提供的AlertDialog都適用。

設置Dialog的大小

兩種實現方式:

第一種方式 通過dialog.getWindow().setLayout(100,100); 設置大小。

第二種方式 通過dialog.getWindow().getAttributes();設置。



    /**
     * 設置大小
     * @param view
     */
    public void dialog_size(View view) {

        SimpleDialog dialog = new SimpleDialog(this);

//        // 第一種方式
//        dialog.getWindow().setLayout(100,100);


        // 第二種方式  獲取參數
        WindowManager.LayoutParams params = dialog.getWindow().getAttributes();

        // 設置高度
        params.height = 100;

        // 設置寬度
        params.width = 100;

        // 設置
        dialog.getWindow().setAttributes(params);


        dialog.show();
    }
其實第一種方式,在其內部實現上也是通過第二種方式設置的。 第二種方式獲取到的params ,裡面包含了很多dialog的顯示屬性,不是只要高度和寬度。

該大小的設置方法對所有的dialog都適用,即之前系統提供的AlertDialog都適用。

該博客中的源碼已經更新到github,有需要者請移步。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved