1. 程式人生 > >Android自定義Dialog對話方塊的幾種方法(精簡版)

Android自定義Dialog對話方塊的幾種方法(精簡版)

自定義對話方塊是經常使用的功能,我們常用的彈窗操作,除了使用popwindow就是使用dialog來實現,這兩種元件都支援之定義佈局和功能來滿足我們個性化的需求,也可以不採用自定義而直接使用系統封裝好的api來實現功能。今天簡單總結下在使用dialog做彈窗功能的方法和會遇到的問題與解決方案。
方法一:直接使用系統的,不自定義佈局和功能方式

		/* @setIcon 設定對話方塊圖示
         * @setTitle 設定對話方塊標題
         * @setMessage 設定對話方塊訊息提示    
         */
        final AlertDialog.Builder normalDialog = 
            new AlertDialog.Builder(MainActivity.this);
        normalDialog.setIcon(R.drawable.icon_dialog);
        normalDialog.setTitle("我是一個普通Dialog")
        normalDialog.setMessage("你喜歡系統對話方塊嗎?");
        normalDialog.setPositiveButton("確定", 
            new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                //...To-do
            }
        });
        normalDialog.setNegativeButton("關閉", 
            new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                //...To-do
            }
        });
        
        //如果想自定義三個按鈕的對話方塊,可以把下面的方法註釋開啟
//            normalDialog.setNeutralButton("第三個按鈕",
//                    new DialogInterface.OnClickListener() {
//                        @Override
//                        public void onClick(DialogInterface dialog, int which) {
//                            // ...To-do
//                        }
//                    });
        // 顯示
        normalDialog.show();

方法二:採用自定義佈局和功能方式

自定義對話方塊佈局: high_opinion_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:paddingTop="@dimen/dp_20"
    android:paddingBottom="@dimen/dp_10"
    android:paddingLeft="@dimen/dp_15"
    android:paddingRight="@dimen/dp_15"
    android:orientation="vertical">

        <TextView
            android:text="Rate US"
            android:gravity="center"
            android:textSize="@dimen/sp_18"
            android:textColor="@color/black"
            android:layout_gravity="center_horizontal"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <TextView
            android:text="We're glad you're enjoying using our app! Would you mind giving us a review?"
            android:gravity="center"
            android:textSize="@dimen/sp_12"
            android:layout_marginTop="@dimen/dp_5"
            android:textColor="@color/black"
            android:layout_gravity="center_horizontal"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_marginTop="@dimen/dp_15"
            android:layout_height="@dimen/dp_37">

            <Button
                android:id="@+id/btn_cancel_high_opion"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:text="Maybe later"
                android:background="@drawable/btn_cancer_high_opion_shape"
                android:textColor="@color/white"
                android:layout_weight="1"/>

            <View
                android:layout_width="@dimen/dp_20"
                android:layout_height="match_parent"
                />
            <Button
                android:id="@+id/btn_agree_high_opion"
                android:layout_width="0dp"
                android:text="Sure"
                android:textColor="@color/white"
                android:background="@drawable/btn_agree_high_opinion_shape"
                android:layout_height="match_parent"
                android:layout_weight="1"/>

        </LinearLayout>



</LinearLayout>

然後在activity或者fragment中想要加點選彈出對話方塊的控制元件的監聽事件中呼叫初始化下面方法

public class HomeActivity extends AppCompatActivity{
	@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);   
        setContentView(R.layout.activity_home);
        
        Button btn= findViewById(R.id.btn)
        //點選按鈕彈出對話方塊
        btn.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
				       showDialog();
                    }
                });

   }
   
//初始化並彈出對話方塊方法
private void showDialog(){
 View view = LayoutInflater.from(this).inflate(R.layout.high_opinion_dialog_layout,null,false);
        final AlertDialog dialog = new AlertDialog.Builder(this).setView(view).create();

        Button btn_cancel_high_opion = view.findViewById(R.id.btn_cancel_high_opion);
        Button btn_agree_high_opion = view.findViewById(R.id.btn_agree_high_opion);

        btn_cancel_high_opion.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SharedPreferencesUnitls.setParam(getApplicationContext(),"HighOpinion","false");
               //... To-do
                dialog.dismiss();
            }
        });

        btn_agree_high_opion.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //... To-do
                dialog.dismiss();
            }
        });

                dialog.show();
            //此處設定位置窗體大小,我這裡設定為了手機螢幕寬度的3/4  注意一定要在show方法呼叫後再寫設定視窗大小的程式碼,否則不起效果會
            dialog.getWindow().setLayout((ScreenUtils.getScreenWidth(this)/4*3),LinearLayout.LayoutParams.WRAP_CONTENT);
}

}

此處附上ScreenUtils工具類程式碼

public class ScreenUtils {

    /**
     * 獲取螢幕高度(px)
     */
    public static int getScreenHeight(Context context) {
        return context.getResources().getDisplayMetrics().heightPixels;
    }
    /**
     * 獲取螢幕寬度(px)
     */
    public static int getScreenWidth(Context context) {
        return context.getResources().getDisplayMetrics().widthPixels;
    }

}

需要注意的問題總結:系統的dialog的寬度預設是固定的,即使你自定義佈局的怎麼修改寬高也不起作用,如果想修改彈出窗體大小,可以使用下面這段程式碼在呼叫dialog.show()方法之後來實現改變對話方塊的寬高的需求

		//此處設定位置窗體大小,
        dialog.getWindow().setLayout(width,height);

Android4.0的Alertdialog對話方塊,設定點選其他位置不消失

Android4.0以上AlertDialog,包括其他自定義的dialog,在觸控對話方塊邊緣外部,對話方塊消失。

可以設定這麼一條屬性,當然必須先AlertDialog.Builder.create()之後才能呼叫這兩個方法

方法一:

setCanceledOnTouchOutside(false);呼叫這個方法時,按對話方塊以外的地方不起作用。按返回鍵還起作用

方法二:

setCancelable(false);呼叫這個方法時,按對話方塊以外的地方不起作用。按返回鍵也不起作用

改變Android Dialog彈出後的Activity背景亮度:
在程式碼中修改.lp.alpha大小隨自己要求設定

// 設定螢幕背景變暗
private void setScreenBgDarken() {
    WindowManager.LayoutParams lp = getWindow().getAttributes();
    lp.alpha = 0.5f;
    lp.dimAmount = 0.5f;
    getWindow().setAttributes(lp);
}
// 設定螢幕背景變亮
private void setScreenBgLight() {
        WindowManager.LayoutParams lp = getWindow().getAttributes();
    lp.alpha = 1.0f;
    lp.dimAmount = 1.0f;
    getWindow().setAttributes(lp);
}

再補充一點爬坑的經驗:
有時候會遇到定義dialog佈局的時候出現加載出來的彈窗和自己佈局裡面定義的大小寬高不一致的效果,然後用dialog.getWindow().setLayout(width,height)方法怎麼設定調節都不管用,我就遇到過一次,特別坑,後來發現了一點造成這種異常情況的原因:
出現問題時的dialog佈局程式碼:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="@dimen/dp_310"
    android:layout_height="@dimen/dp_236"
    android:background="@drawable/wallpaper_downloadorsace_outside_shape">


    <RelativeLayout
        android:id="@+id/rl_close_dialog"
        android:layout_width="@dimen/dp_40"
        android:layout_height="@dimen/dp_40">

        <ImageView
            android:id="@+id/iv_close_dialog"
            android:layout_width="@dimen/dp_15"
            android:layout_height="@dimen/dp_15"
            android:scaleType="fitXY"
            android:layout_marginLeft="@dimen/dp_14"
            android:layout_marginTop="@dimen/dp_12"
            android:src="@drawable/icon_close" />

    </RelativeLayout>



    <RelativeLayout
        android:layout_marginTop="@dimen/dp_46"
        android:layout_marginBottom="@dimen/dp_35"
        android:layout_centerInParent="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">


        <LinearLayout
            android:id="@+id/ll_localsave_out"
            android:layout_width="@dimen/dp_215"
            android:layout_height="@dimen/dp_53"
            android:layout_centerHorizontal="true"
            android:background="@drawable/wallpaper_downloadorsace_shape"
            android:gravity="center">

            <LinearLayout
                android:id="@+id/ll_localsave"
                android:background="@drawable/local_save_water_selector"
                android:clickable="true"
                android:gravity="center"
                android:layout_width="match_parent"
                android:layout_height="match_parent">
                <!--android:background="?android:attr/selectableItemBackground"   系統自帶水波紋效果 -->

                <ImageView
                    android:layout_width="@dimen/dp_22"
                    android:layout_height="@dimen/dp_28"
                    android:scaleType="fitXY"
                    android:src="@drawable/icon_phone" />

                <com.blossom.ripple.widget.AvenirNextRegularTextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="@dimen/dp_7"
                    android:text="Local save"
                    android:textColor="@color/white"
                    android:textSize="@dimen/sp_17" />

            </LinearLayout>



        </LinearLayout>

        <LinearLayout
            android:layout_alignParentBottom="true"
            android:layout_marginBottom="@dimen/dp_45"
            android:layout_width="@dimen/dp_215"
            android:layout_height="@dimen/dp_53"
            android:layout_centerHorizontal="true"
            android:background="@drawable/wallpaper_downloadorsace_shape"
            android:gravity="center">
           


        <LinearLayout
            android:id="@+id/ll_setaswallpaper"
            android:background="@drawable/local_save_water_selector"
            android:clickable="true"
            android:gravity="center"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <!--android:background="?android:attr/selectableItemBackground"   系統自帶水波紋效果 -->


            <ImageView
                android:layout_width="@dimen/dp_28"
                android:layout_height="@dimen/dp_24"
                android:scaleType="fitXY"
                android:src="@drawable/icon_album" />

            <com.blossom.ripple.widget.AvenirNextRegularTextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="@dimen/dp_5"
                android:text="Set as wallpaper"
                android:textColor="@color/white"
                android:textSize="@dimen/sp_17" />
        </LinearLayout>

        </LinearLayout>

    </RelativeLayout>

</RelativeLayout>

執行效果如下圖
在這裡插入圖片描述
執行出來的效果很頭痛,雖然我在佈局程式碼裡面寫死了彈窗佈局的寬高大小,然後想通過window的setlayout方法控制改變彈窗的大小,但無論如何都不行,後來仔細檢查佈局程式碼發現了貓膩,在一個子佈局LinearLayout的標籤下引用了一個android:layout_alignParentBottom="true"的屬性,然後稍微調整了下程式碼再次執行便解決了上面的問題。下面貼下修改後的正確程式碼,我在裡面加了問題原因的註釋還:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="@dimen/dp_310"
    android:layout_height="@dimen/dp_236"
    android:background="@drawable/wallpaper_downloadorsace_outside_shape">


    <RelativeLayout
        android:id="@+id/rl_close_dialog"
        android:layout_width="@dimen/dp_40"
        android:layout_height="@dimen/dp_40">

        <ImageView
            android:id="@+id/iv_close_dialog"
            android:layout_width="@dimen/dp_15"
            android:layout_height="@dimen/dp_15"
            android:scaleType="fitXY"
            android:layout_marginLeft="@dimen/dp_14"
            android:layout_marginTop="@dimen/dp_12"
            android:src="@drawable/icon_close" />

    </RelativeLayout>



    <RelativeLayout
        android:layout_marginTop="@dimen/dp_46"
        android:layout_marginBottom="@dimen/dp_35"
        android:layout_centerInParent="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">


        <LinearLayout
            android:id="@+id/ll_localsave_out"
            android:layout_width="@dimen/dp_215"
            android:layout_height="@dimen/dp_53"
            android:layout_centerHorizontal="true"
            android:background="@drawable/wallpaper_downloadorsace_shape"
            android:gravity="center">

            <LinearLayout
                android:id="@+id/ll_localsave"
                android:background="@drawable/local_save_water_selector"
                android:clickable="true"
                android:gravity="center"
                android:layout_width="match_parent"
                android:layout_height="match_parent">
                <!--android:background="?android:attr/selectableItemBackground"   系統自帶水波紋效果 -->

                <ImageView
                    android:layout_width="@dimen/dp_22"
                    android:layout_height="@dimen/dp_28"
                    android:scaleType="fitXY"
                    android:src="@drawable/icon_phone" />

                <com.blossom.ripple.widget.AvenirNextRegularTextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="@dimen/dp_7"
                    android:text="Local save"
                    android:textColor="@color/white"
                    android:textSize="@dimen/sp_17" />

            </LinearLayout>



        </LinearLayout>

        <LinearLayout
            android:layout_width="@dimen/dp_215"
            android:layout_height="@dimen/dp_53"
            android:layout_centerHorizontal="true"
            android:layout_below="@+id/ll_localsave_out"
            android:layout_marginTop="@dimen/dp_30"
            android:background="@drawable/wallpaper_downloadorsace_shape"
            android:gravity="center">
            <!--android:layout_alignParentBottom="true"    這個屬性曾經導致過彈窗特別大,會挨著螢幕頂部和底部-->


        <LinearLayout
            android:id="@+id/ll_setaswallpaper"
            android:background="@drawable/local_save_water_selector"
            android:clickable="true"
            android:gravity="center"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <!--android:background="?android:attr/selectableItemBackground"   系統自帶水波紋效果 -->


            <ImageView
                android:layout_width="@dimen/dp_28"
                android:layout_height="@dimen/dp_24"
                android:scaleType="fitXY"
                android:src="@drawable/icon_album" />

            <com.blossom.ripple.widget.AvenirNextRegularTextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="@dimen/dp_5"
                android:text="Set as wallpaper"
                android:textColor="@color/white"
                android:textSize="@dimen/sp_17" />
        </LinearLayout>

        </LinearLayout>
    </RelativeLayout>

</RelativeLayout>

問題解決後感覺又積累了一點彈窗方面的經驗,收穫滿滿的,趕緊記錄下來吧,省的以後忘記了再犯同樣的錯誤!

今天的分享先到這裡,後續會不斷新增和更新更多更好的學習資料,如果你喜歡可以關注加好友,互相探討學習,我們互相學習一起成長!

相關推薦

Android定義Dialog對話方塊方法精簡

自定義對話方塊是經常使用的功能,我們常用的彈窗操作,除了使用popwindow就是使用dialog來實現,這兩種元件都支援之定義佈局和功能來滿足我們個性化的需求,也可以不採用自定義而直接使用系統封裝好的api來實現功能。今天簡單總結下在使用dialog做彈窗功能

Android定義Dialog對話方塊消除邊距消除黑邊框和顯示動畫

這兩天練習一個專案 顯示對話方塊類似於QQ發表說說,寬是充滿螢幕的 並且有上下的顯示隱藏動畫 但是AlertDialog預設顯示模式是有邊距的 用了很多方法怎麼也消除不了AlertDialog的邊距 如下圖這樣 後來選擇使用Dialog消除了預設邊距的

Android定義AlertDialog對話方塊並回傳Activity引數

需求 開發過程總會想要自己設計的對話方塊,有時候還需要在activity獲取對話方塊的一些操作結果。 思路 1.自定義對話方塊,並繼承AlertDialog 2.在自定義對話方塊中,定義一個介面,並宣告一個方法,將操作結果作為方法引數 3.在act

Android定義圓角對話方塊

自定義對話方塊MyDialog類繼承Dialog類: package com.example.jjy.myapplication; import android.app.Dialog; import android.content.Context; import andr

js利用閉包封裝定義模塊的方法

暴露 使用 模塊化 function 一個 com 調用方法 urn ted 1.自定義模塊:   具有特定功能的js文件   將所有的數據和功能都封裝在一個函數的內部   只向外暴露一個包含有n個方法的對象或者函數   模塊使用者只需要通過模塊暴露的對象調用方法來

Android--定義View滑動的六方法

概述 由於移動平臺螢幕尺寸大小的限制,為了給使用者呈現更好的頁面內容,我們需要通過滑動來實現一些頁面內容的顯示和隱藏操作。 自定義View的方法 View.layout()方法 改變view的佈局引數LayoutParams View.offsetL

android定義控制元件之圓形進度條帶動畫

首先貼上圖片: 額,感覺還行吧,就是進度條的顏色醜了點,不過咱是程式設計師,不是美工,配色這種問題當然不在考慮範圍之內了 下面說重點,如何來寫一個這樣的自定義控制元件。 首先,需要有一個灰色的底圖,來作為未填充時的進度條; 然後,根據傳入的當前進度值,繪製填充時的進度圓

Android 定義控制元件之命運之輪抽獎轉盤

1 思路 首先肯定是要繪製扇形的,每一個獎品為一個扇形區分開,然後在扇形中得有當前獎品的說明,最後讓這個輪盤轉起來就行了。說起來很簡單,但是在繪製的時候,特別是繪製文字的時候還有有一些細節需要注意的,也不是難點,只是要理清楚那些地方應該怎麼去畫,怎麼獲取需要繪製的座標。  

Leetcode|Longest Palindromic Substring(最長迴文的方法)Manacher演算法

Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there ex

讀取視訊幀的方法自己整理

1、第一種方法 #include "opencv2/opencv.hpp" using namespace cv; int main(int, char**) { VideoCapture cap(

CSS清除浮動的方法有例項

首先我們要說一下浮動帶給我們的問題:如果父元素沒有設定固定高度那麼當子元素設定浮動時父元素不會被撐開,很明顯這會影響我們的佈局 效果如下: 1、第一種方法:after偽元素(推薦使用) 給浮動元素的父元素新增類名clearfix並設定clearfix的css /*第一種

js清除瀏覽器快取的方法專案總結

以前很少關注這方面的問題,直達我們的技術經理找我們說要換框架,為什麼換框架呢,因為快取的問題,原來的專案是用版本號作為重新整理的依據的。因為微信 公眾號上有這樣一個機制,使用版本好的話,有時做不到及時重新整理,所以就用了vue.js,因為它有這樣的功能就是如果某個檔案裡面的

SpringBoot給容器中註冊元件的四方法簡易

本文介紹的方法比較簡潔,需要有Spring基礎 方法一:包掃描+註解 1.配置類,標明註解掃描的範圍 //告訴Spring這是一個配置類 @Configuration //註解所掃描的範圍,類似於spring配置檔案的 context:component-scan

Android--定義Dialog,仿IOS對話方塊樣式

效果: 實現: 1.dialog_layout.xml: <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/ap

Android定義Dialog,炫酷主流的載入對話方塊

前言  最近開發中用到許多對話方塊,之前都是在外面的程式碼中建立AlertDialog並設定自定義佈局實現常見的對話方塊,諸如更新提示等含有取消和刪除兩個按鈕的對話方塊我們可以通過程式碼建立一個AlertDialog並通過它暴露的一系列方法設定我們自定義的佈局

Android實現定義圓角對話方塊Dialog

前言:   專案中多處用到對話方塊,用系統對話方塊太難看,就自己寫一個自定義對話方塊。         對話方塊包括:1、圓角         2、app圖示 , 提示文字,關閉對話方塊的"確定"按鈕   難點:1、對話方塊邊框圓角顯示      2、考慮到提示文字字數不確定,在不影響美觀的情況下,需要在一

Android定義Dialog多選對話Dialog+Listview+CheckBox)

dia bundle adapter get etl wrap 點擊 所有 技術 先放效果截圖 項目中需要有個Dialog全選對話框,點擊全選全部選中,取消全選全部取消。下午查了些資料,重寫了一下Dialog對話框。把代碼放出來。 public class MainAct

Android定義介面卡父類繼承BaseAdapter,定義生成對話方塊工具類

工作內容: 1.不使用SQLiteHelper獲取本地資料庫中的表的內容 2.自定義介面卡父類 3.自定義生成對話方塊的工具類 學習分享: 1.不使用SQLiteHelper,直接找到本地資料庫檔案開啟,並獲取其中的表內容 SQLiteDatabase  sqliteDat

android 定義dialog的實現方法

listener params .get animator miss nim style wrap 參數 最近一直在做 java 相關的東西, 雖然一直在看 Android 但感覺有點留於理論,總這樣畢竟不行,寫的多不一定懂得多,但要想懂得多就一定要寫的多,於是今天動手寫了

Android 定義Dialog小結

關於自定義佈局的Dialog,總是會遇到各種各樣的問題,作為一個菜鳥,想想還是打算專門開一篇總結自己遇到的各種問題。歡迎大佬們指點 自定義佈局寬度和位置問題 自定義佈局,就是自己自由地設定Dialog的樣式,所以肯定會自己寫一個Layout佈局,並把它加載出來,這才是我們想要的,但是經常會出