Android 對話框相關總結

常用的對話框相關的有:AlertDialog,ProgressDialog,自定義的對話框(自定義的對話框的長寬設置需要注意),還有任意位置在其他應用上都可以彈出的對話框。其中任意位置在其他應用上都可以彈出的對話框見另一篇博文:點擊跳轉。該博文的demo放在gihub上:點擊跳轉。只有“將事件傳遞迴對話框的宿主”的例子在module:”passEventToHost”裏,其他都在dialog裏。

1.純粹的 AlertDialog以及設置位置

AlertDialog對話框是非常常用的對話框,一般又一個頭部,中間的說明文字和下面的按鈕組成。按鈕的數量可以是:1、2或3。注意的是,下面按鈕中,最前面到的那個按鈕,在Android的不同版本中,位置是不同的。
下面給出代碼:

 AlertDialog.Builder dialog = new AlertDialog.
                Builder(MainActivity.this);
        dialog.setTitle("對話框最上面的字");//對話框最上面的字
        dialog.setMessage("對話框中部的字");//對話框中部的字
        dialog.setCancelable(false);//如果是false,點擊其他位置或者返回鍵無效,這個地方默認爲true
//以下爲對話框最下面的選擇項
        dialog.setPositiveButton("右邊", new DialogInterface.
                OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Toast.makeText(MainActivity.this, "右邊", Toast.LENGTH_SHORT).show();
            }

        });
        //需要第二個按鈕才添加如下的setNegativeButton()
        dialog.setNegativeButton("左邊", new DialogInterface.
                OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Toast.makeText(MainActivity.this, "左邊", Toast.LENGTH_SHORT).show();
            }

        });
        //需要第三個按鈕時,才添加如下的setNeutralButton(),android老版本是在中間,比如4.0,在新版本是在前面,沒有研究從哪個版本開始變的
        dialog.setNeutralButton("前面", new DialogInterface.
                OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Toast.makeText(MainActivity.this, "前面", Toast.LENGTH_SHORT).show();
                dialog.dismiss();
            }
        });
        dialog.show();

在Android 8.0 模擬器上運行效果:

這裏寫圖片描述

2. ProgressDialog和自定義對話框

雖然,ProgressDialog官方在Androidd 8.0中已經棄用它了:“This class was deprecated in API level 26.“,但是實際用Android 8.0模擬器運行並沒有出現問題。而且官網沒有給出效果相同的直接代替的類。只是建議用別的東西代替,如ProgressBar。
下面給出代碼:

ProgressDialog progressDialog = new ProgressDialog
                (MainActivity.this);
        progressDialog.setTitle("對話框上部的字");
        progressDialog.setMessage("正在加載.....");
        progressDialog.setCancelable(true);//如果是false,點擊其他位置或者返回鍵無效,默認爲true
        progressDialog.show();
        //progressDialog.dismiss();//此句讓progressDialog消失

在Android 8.0 模擬器上運行效果:
這裏寫圖片描述
自定義對話框
下面給出一個簡單的,避開棄用progressDialog問題的方法:自定義對話框。通過getInflater.inflate(R.layout.dialog_layout, null)獲取View;通過builder.setView()給對話框設置view。這樣設置的Dialog寬度始終會如右圖下圖所示,而高度是wrap_content且有一個最小值,不會比那個值小,在
佈局文件dialog_layout.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="20dp"
        android:layout_marginStart="20dp"
        android:layout_marginTop="15dp"
        android:orientation="horizontal">
        <ProgressBar

            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <TextView
            android:id="@+id/message"
            android:layout_marginLeft="20dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:text="message"
            android:textSize="17sp"/>
    </LinearLayout>
</LinearLayout>

java代碼如下,通過message.setText()改變下方顯示文字, builder.setTitle()設置上方顯示文字。

 AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
        LayoutInflater inflater = getLayoutInflater();
        View dialogView = inflater.inflate(R.layout.dialog_layout, null);
        builder.setView(dialogView).create();
        builder.setTitle("進度");
        TextView message = dialogView.findViewById(R.id.message);
        message.setText("進度:%10");
        builder.show();

下面對比一下,效果基本與ProgressDialog一致:

這裏寫圖片描述

3. 自定義對話框(考慮wrap_content時的大小問題)

自定義對話框,就是自己寫一個佈局,讓對話框加載佈局,並且能監聽這個佈局裏面的點擊事件,並且對話框可以響應點擊消失。需要注意的是,有時候自定義的根佈局高和寬是wrap_content,這時定義的對話框長寬會失效,下面是考慮到這種問題的自定義對話框。但是比較麻煩,如果根佈局大小可以寫死,就不需要考慮這個問題
首先寫一個對話框的佈局:my_dialog.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:background="@color/colorAccent"
              android:orientation="vertical">

    <TextView
        android:layout_width="300dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="自定義對話框"
        android:textSize="20sp"/>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginTop="20dp">

        <Button
            android:id="@+id/leftBt"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="左按鈕"/>

        <Button
            android:id="@+id/rightBt"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="右按鈕"/>
    </LinearLayout>

</LinearLayout>

設計對話框的style,目的是去控制對話框長寬,並且避免出現一些上部陰影,下面是添加在styles.xml中的代碼,其中windowIsFloating讓java代碼部分控制大小生效,windowNoTitle避免出現一些上部陰影:

<style name="style_dialog" parent="android:style/Theme.Dialog">
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowIsFloating">true</item>
    </style>

在java代碼部分會用到上面的文件,注意一點:導入的AlertDialog語句是:import android.support.v7.app.AlertDialog;(不要導入錯誤成另一個)

 //獲取自定義佈局view實例
        View layout = LayoutInflater.from(this).inflate(R.layout.my_dialog, null);
        //在對話框里加載佈局:setView()方法
        final AlertDialog.Builder dialog = new AlertDialog.
                Builder(MainActivity.this,R.style.style_dialog);
        dialog.setCancelable(false)//如果是false,點擊其他位置或者返回鍵無效,這個地方默認爲true
                .setView(layout);//這裏加載佈局
        final AlertDialog alert = dialog.create();

        //設置對話框的寬和高(注意,設置長寬還需要設置R.style.style_dialog,否則會出現很多問題),
        //並且如果需要設置佈局大小,而不是wrap_content,那麼需要在佈局的子項裏面設置大小,
        //直接在最外層設置是無效的
        Window window = alert.getWindow();
        window.getDecorView().setPadding(0, 0, 0, 0);//void setPadding (int left, int top,int right,int bottom)
        WindowManager.LayoutParams lp = window.getAttributes();
        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
        window.setAttributes(lp);
        window.setGravity(Gravity.CENTER);//對話框出現的位置

        //按鈕監聽事件
        Button btLeft, btRight;
        btLeft = layout.findViewById(R.id.leftBt);
        btRight = layout.findViewById(R.id.rightBt);
        btLeft.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //這裏寫左按鈕點擊響應事件
                Toast.makeText(MainActivity.this, "左按鈕", Toast.LENGTH_SHORT).show();
                alert.dismiss();//讓對話框消失
            }
        });

        btRight.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //這裏寫右按鈕點擊響應事件
                Toast.makeText(MainActivity.this, "右按鈕", Toast.LENGTH_SHORT).show();
                alert.dismiss();//讓對話框消失
            }
        });
        alert.show();
    }

在擬器上運行效果:
這裏寫圖片描述

4.單選列表對話框

添加builder.setItems()即可,setItems第一個參數是顯示數據的數組,第二個是點擊監聽DialogInterface.OnClickListener對象。也可以使用 setAdapter() 指定一個列表。 這樣一來,您就可以使用 ListAdapter 以動態數據(如來自數據庫的數據)支持列表。

 String[] arr={"第一項","第二項","第三項"};
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("單選列表對話框")
                .setItems(arr, new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        // which是點擊列表位置
                        Toast.makeText(MainActivity.this, which+"", Toast.LENGTH_SHORT).show();
                    }
                });
         builder.create().show();
    }

效果是這樣的:
這裏寫圖片描述

5.多選列表對話框

需要定義一個List對象存儲選定內容,在點擊確定時讀取。依靠setMultiChoiceItems()方法實現多選列表對話框。

List <String>mSelectedItems;//用於多選列表對話框選擇項的暫時存儲


String[] arr={"第一項","第二項","第三項"};
        mSelectedItems = new ArrayList();  //用來存放被選中的項
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        // Set the dialog title
        builder.setTitle("多選列表對話框")
                // Specify the list array, the items to be selected by default (null for none),
                // and the listener through which to receive callbacks when items are selected
                .setMultiChoiceItems(arr, null,
                        new DialogInterface.OnMultiChoiceClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which,
                                                boolean isChecked) {
                                if (isChecked) {
                                    // 如果選擇一項,那麼在選定的項中添加此項
                                    mSelectedItems.add(which+"");
                                } else if (mSelectedItems.contains(which)) {
                                    // 如果取消選擇,那麼在選定的項中移除此項
                                    mSelectedItems.remove(Integer.valueOf(which));
                                }
                            }
                        })
                // Set the action buttons
                .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int id) {
                        //確定
                        String result="";
                        for(String str:mSelectedItems){
                            result+=str;
                        }
                        //這裏輸出被選中項
                        Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT).show();
                    }
                })
                .setNegativeButton("cancel", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int id) {
                        //取消
                    }
                });

         builder.create().show();

效果如下:
這裏寫圖片描述

6.全屏的對話框

1.狀態欄消失,屏幕全部佔滿的對話框

建議使用Dialog而不是AlertDialog,因爲AlertDialog自帶的一些屬性使全屏變得比Dialog麻煩一些。Dialog與AlertDialog代碼上的區別,主要是它沒有Builder,而是直接在Dialog上對對話框屬性進行設置。而要讓Dialog全屏是非常簡單的,只需要在實例化Dialog對象時像這樣傳遞參數即可。注意,這樣的話,屏幕上方狀態欄也會消失,對話框佔據整個屏幕(除虛按鍵)。

Dialog dialog = new Dialog(this,android.R.style.
Theme_Light_NoTitleBar_Fullscreen);

完整的一個自定義佈局的全屏對話框代碼:

public showDialog(Activity activity){
Dialog dialog = new Dialog(activity,
android.R.style.Theme_Light_NoTitleBar_Fullscreen);//第二參數爲關鍵代碼
        View view = LayoutInflater.from(activity).
        inflate(R.layout.diag_list, null, false);//diag_list是對話框的佈局文件
        dialog.setContentView(view);
        //這裏區別於AlertDialog,Builder的setView(View)

        dialog.show();
}

下面在提供一種狀態欄不消失的全屏對話框的方法:

2.讓狀態欄顯示的全屏對話框

需要設置對話框長寬都是match_parent,因爲默認是wrap_content

dialog.getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager
                .LayoutParams.MATCH_PARENT);

需要設置Dialog的背景,因爲它默認背景會距離屏幕上下左右各8dp

dialog.getWindow().setBackgroundDrawable(null);
//注意,以上寫法會使dialog背景透明,可以在對話框佈局文件中設置佈局背景色。
//或像下面一樣,設背景色爲白色
//dialog.getWindow().setBackgroundDrawable(new 
//ColorDrawable(getResources().getColor(android.R.color.white)));

以上兩步可以使Dialog全屏(不包含狀態欄),下面一個完整例子:


 public void showDialog(Activity activity) {
        Dialog dialog = new Dialog(activity);//一個參數
        View view = LayoutInflater.from(activity).inflate(R.layout.diag_list, null, false);
        dialog.setContentView(view);

        dialog.getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager
                .LayoutParams.MATCH_PARENT);
        dialog.getWindow().setBackgroundDrawable(new ColorDrawable(activity.getResources().getColor(android.R.color.white)));
        dialog.show();

    }
發佈了57 篇原創文章 · 獲贊 59 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章