Skip to content

自定义对话框 CustomDialog

Kongzue edited this page May 17, 2024 · 20 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();

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