Skip to content

CustomDialog_tc

Kongzue edited this page Sep 14, 2024 · 6 revisions

🌐 View English Document | 简体中文文档

📐自訂對話框 CustomDialog

自訂對話框 CustomDialog

根據訂製化自由度的對話框組件,完全由用戶自行實現布局內容。CustomDialog 提供了 ALIGN 選項可以輕鬆訂製對話框彈出的方式,默認支持螢幕中央、螢幕底部和螢幕頂部三種彈出模式,也會提供相應的彈出動畫效果,當然用戶也可以自訂動畫效果。

顯示一個簡單自訂對話框

首先準備一個自訂布局,然後使用以下代碼顯示一個自訂對話框:

CustomDialog.show(new OnBindView<CustomDialog>(R.layout.layout_custom_dialog) {
    @Override
    public void onBind(final CustomDialog dialog, View v) {
        ImageView btnOk;
        btnOk = v.findViewById(R.id.btn_ok);
        btnOk.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dialog.dismiss();
            }
        });
    }
});

上述代碼示範了 onBind 回調方法中如何綁定實例化組件和設置事件的過程。

你也可以使用 build() 方法構建 CustomDialog:

CustomDialog.build()
    .setCustomView(new OnBindView<CustomDialog>(R.layout.layout_custom_dialog) {
        @Override
        public void onBind(final CustomDialog dialog, View v) {
            ImageView btnOk;
            btnOk = v.findViewById(R.id.btn_ok);
            btnOk.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    dialog.dismiss();
                }
            });
        }
    })
    .show();

使用 ViewBinding 的話也可以更換為 OnBindingView 來實現直接通過 binding 獲取佈局實例:

FullScreenDialog.show(new OnBindingView<FullScreenDialog, LayoutCustomViewBinding>() {
            @Override
            public void onBind(FullScreenDialog dialog, View view, LayoutCustomViewBinding binding) {
                //View childView = binding.childView
            }
        });

CustomDialog 的自訂選項

CustomDialog 默認支持對話框從螢幕頂部/底部/中央進行顯示的設置 Align,且不同的 Align設置附帶有不同的默認啟動動畫,例如從螢幕中央啟動的對話框是採用默認消息對話框的動畫顯示的,而從螢幕頂部/底部顯示和關閉的對話框,則默認採用下滑/上滑的平移+漸變動畫顯示效果,當然,如果有需要也可以自訂動畫效果。

設置 Align 來修改 CustomDialog 的啟動方式:

CustomDialog.show(...)
    .setAlign(ALIGN.TOP);

ALIGN 是一個枚舉,其值定義如下:

CENTER			中央顯示(默認)
TOP			頂部顯示(等同於頂部中央)
TOP_CENTER		頂部中央顯示
TOP_LEFT		頂部左側顯示
TOP_RIGHT		頂部右側顯示
BOTTOM			底部顯示(等同於底部中央)
BOTTOM_CENTER		底部中央顯示
BOTTOM_LEFT		底部左側顯示
BOTTOM_RIGHT		底部右側顯示
LEFT			左側顯示(等同於左側中央)
LEFT_CENTER		左側中央顯示
LEFT_TOP		左側上方顯示
LEFT_BOTTOM		左側下方顯示
RIGHT			右側顯示(等同於右側中央)
RIGHT_CENTER		右側中央顯示
RIGHT_TOP		右側上方顯示
RIGHT_BOTTOM		右側下方顯示

**請注意:**其中,例如頂部左側顯示 TOP_LEFT 和左側上方顯示 LEFT_TOP 的區別在於入場出場動畫方向不一樣,頂部左側顯示的動畫是從螢幕頂部進入,布局居於螢幕左側,而左側上方顯示則是動畫從螢幕左側進入,居於上方顯示。

您也可以自訂啟動/關閉動畫,支持使用自訂的 anim 資源文件進行設置:

CustomDialog.build()
    .setCustomView(...)
    .setEnterAnimResId(R.anim.enter_anim)
    .setExitAnimResId(R.anim.exit_anim)
    .show();

或:

CustomDialog.build()
    .setCustomView(...)
    .setAnimResId(R.anim.enter_anim, R.anim.exit_anim)
    .show();

請注意,啟動動畫必須在對話框啟動前設置,即使用build()方法構建對話框進行設置。

基於 view 的位置顯示

你可以指定一個界面上已存在的 view,使 CustomDialog 圍繞其位置顯示

.setAlignBaseViewGravity(btnCustomDialogAlign, Gravity.TOP)

alignGravity 可指定 TOPLEFTRIGHTBOTTOM 並組合使用 CENTER_VERTICALCENTER_HORIZONTAL 相對橫向或縱向居中,也可以設置完全居中疊加 CENTER,其顯示效果如下:

基於 view 的位置顯示

  • 注意此方法將設置 CustomDialog 為全螢幕模式(setFullScreen(true))

額外的,還可以指定基於 view 位置顯示時,與 view 之間的間距:

.setBaseViewMargin(marginLeft, marginTop, marginRight, marginBottom)

也可以單獨指定:

.setBaseViewMarginLeft(marginLeft)

背景遮罩

CustomDialog 默認不實現對話框背景遮罩,這是為了豐富擴展性。如果需要背景遮罩,您可以自行使用如下代碼設置:

customDialog.setMaskColor(colorInt);

請注意,傳入參數為 ColorInt 值,您可以使用 Color.parseColor("#4D000000") 設置一個 HEX 色值,或使用 getResources().getColor(R.color.black30) 設置一個顏色的資源值。

沉浸式

CustomDialog 預設會開啟沉浸式非安全區隔離模式,也就是說,會在根布局設置一個 padding,將頂部狀態欄和底部導航欄的無法觸控的非安全區位置分離開,保證自訂布局位置一定處於安全區內,但這可能與您使用的沉浸式框架,或者未配置任何沉浸式(即頂部導航欄和底部狀態欄都不沉浸式)時產生衝突,導致 CustomDialog 在使用頂部顯示/底部顯示時額外空出一部分區域,此時您可以使用以下設置關閉沉浸式 padding:

CustomDialog.build()
    .setCustomView(...)
    .setAutoUnsafePlacePadding(false)
    .show();

請注意,setAutoUnsafePlacePadding(Boolean) 必須在對話框啟動前設置,即使用build()方法構建對話框進行設置。

生命週期回調

想要監控對話框的生命週期,可以實現其 .setDialogLifecycleCallback(...) 介面,建議使用build()方法構建對話框:

CustomDialog.build()
        .setDialogLifecycleCallback(new DialogLifecycleCallback<CustomDialog>() {
            @Override
            public void onShow(CustomDialog dialog) {
                //CustomDialog 啟動時回調
            }
            @Override
            public void onDismiss(CustomDialog dialog) {
                //CustomDialog 關閉時回調
            }
        })
        .show();

CustomDialog 也支持 Lifecycle,你可以使用 .getLifecycle() 獲取 Lifecycle 對象。

你也可以透過使用 new 構建實例時,override 的生命週期事件的方式來處理生命週期事務,例如:

//複寫事件示範
new CustomDialog() {
    @Override
    public void onShow(CustomDialog dialog) {
        //...
        tip("onShow");
    }
    @Override
    public void onDismiss(CustomDialog dialog) {
        //...
        tip("onDismiss");
    }
}

你也可以使用方法 .onShow(DialogXRunnable).onDismiss(DialogXRunnable),來處理生命週期事務,例如:

CustomDialog.show(...)
        .onShow(new DialogXRunnable<CustomDialog>() {
            @Override
            public void run(CustomDialog dialog) {
                //CustomDialog show!
            }
        })
        .onDismiss(new DialogXRunnable<CustomDialog>() {
            @Override
            public void run(CustomDialog dialog) {
                //CustomDialog dismiss!
            }
        });

其他額外方法

//強制重新刷新界面
.refreshUI();

//關閉對話框
.dismiss();

//獲取對話框實例化對象,您可以透過此方法更深度的訂製Dialog的功能
.getDialogImpl()

//獲取自訂布局實例
.getCustomView()
    
//設置對話框寬度
.setWidth(px)
    
//設置對話框高度
.setHeight(px)

//隱藏對話框(無動畫),恢復顯示請執行非靜態方法的 .show()
.hide();

//隱藏對話框(模擬關閉對話框的動畫),恢復顯示請執行非靜態方法的 .show()
.hideWithExitAnim();

//是否處於顯示狀態
.isShow()

//使觸摸穿透遮罩層
.setBkgInterceptTouch(false)

//置頂對話框
.bringToFront()

//指定對話框顯示層級
.setThisOrderIndex(int)
Clone this wiki locally