Skip to content

常见问题

Kongzue edited this page Nov 17, 2022 · 43 revisions

ℹ️常见问题

Q:iOS 主题样式无模糊效果

A:请检查是否已经配置 renderscript 支持,具体请查阅[首页](https://github.com/kongzue/DialogX/wiki)文档页面中的《配置 DialogX》部分。

若已经配置,但依然无效果,建议将 Activity 的布局文件背景修改为纯色,不要使用透明色或不设置,例如设置为白色后再试。

若还是无效,请尝试下载运行 Demo,若也没有模糊效果说明设备不支持 renderscript,请选用别的主题。


Q:输入法键盘弹出后遮挡对话框/输入法无法顶起对话框

A:有两个方案可供选择

方案一:优化软件布局设计

针对纵向布局,在布局外层添加 ScrollView 组件即可。

其原因为,当输入法弹出时,如果 Activity 的界面内存在 ScrollView,系统会自动压缩 ScrollView 的高度以实现让界面合理的显示,此时可以触发“底部非安全区”高度的变化,DialogX 可以获取到合适的高度以正常抬起对话框的显示。

方案二:直接使用输入法处理模式:重定界面大小即可。

进入您的项目 AndroidManifest.xml,对 Activity 添加配置:

<activity android:name=".MainActivity"
    android:windowSoftInputMode="adjustResize"
    ...>
...
</activity>

Q:Dialog 主题无法全屏显示

A:请查阅[首页](https://github.com/kongzue/DialogX/wiki)文档页面中的《配置 DialogX》部分并检查 Activity 的 theme 设置,因为实现原理,DialogX 的对话框无法覆盖原生 ActionBar 区域,建议使用 NoActionBar 的 theme。

另外,如果无法覆盖导航栏或显示不全,请将 Activity 实现沉浸式后再试,推荐使用 [BaseFramework 框架](https://github.com/kongzue/BaseFramework)可以自动实现顶部状态栏和底部导航栏的沉浸式效果(Demo 同款)。


Q:BottomDialog / BottomMenu / CustomDialog 显示时出现额外的上下边距

A:因为这些组件可能都涉及沉浸式相关逻辑,DialogX 会在显示时额外的自动空出屏幕四边的“非安全区域”来保证组件内容的正常显示,但也这可能会在未实现沉浸式的应用中出现额外的边距,此时您可以将应用的Activity 沉浸式,包含顶部状态栏透明及底部导航栏背景透明,即可完美解决。

我更建议您使用 BaseFramework 框架的沉浸式方案(https://xiaozhuanlan.com/topic/4276819530)


Q:全屏对话框显示时,Activity 背景变黑

A:请指定设置 Activity 布局文件背景颜色。


Q:启动对话框很慢,点了按钮半天不打开对话框

A:检查主线程逻辑是否出现卡线程的问题,DialogX 之所以可以做到在异步线程启动的原理是 Post 了启动消息到主线程去运行,但主线程循环消息的过程一旦出现阻塞现象就会导致 DialogX 的启动过程无法流畅的执行,建议将耗时的操作放到异步线程运行,尽量减少主线程的工作流程,此问题就不会出现了。


Q:对话框在其他 Activity 启动

A:执行的对话框的 show 指令后,切换了别的 Activity,发现对话框在另一个 Activity 显示。

这个问题的原因和上边一个问题类似,出现了主线程卡线程的问题,而 DialogX 启动是必须等待主线程循环消息执行启动过程的,如果说在处理事务的时候频繁执行 dismiss 关闭指令或 show 指令,以及切换 Activity 的显示可能造成对话框启动依赖的 Activity 判断错误,而 DialogX 默认的启动方法也没有指定依赖的 Activity,这时可以尝试指定启动的 Activity。

方法是使用对话框组件的 build()方法构建对话框,请注意 build() 方法是没有参数的,你需要通过方法设定对话框的其他参数,例如标题、内容、按钮等,最后执行 show(activity) 方法启动对话框,举例如下:

MessageDialog.build()
        .setTitle("Title")
        .setMessage("This is message content.")
        .setOkButton("OK", new OnDialogButtonClickListener<MessageDialog>() {
            @Override
            public boolean onClick(MessageDialog baseDialog, View v) {
                //...
                return false;
            }
        })
        .show(MainActivity.this);	//重点

Q:如何修改输入框光标颜色

A:请在您的 style 中添加以下代码复写:

定义亮色模式时,DialogX 中的 AppCompat 组件主题色:

<style name="DialogXCompatThemeLight" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="colorAccent">@color/colorAccent</item>
</style>

定义暗色模式时,DialogX 中的 AppCompat 组件主题色:

<style name="DialogXCompatThemeDark" parent="Theme.AppCompat.NoActionBar">
    <item name="colorAccent">@color/colorAccent</item>
</style>

DialogX 中的输入框使用的是系统原生组件,并非自定义组件,所以修改方式需要按照原生主题色修改方案来。


Q:在使用 DialogX 后,软件界面出现界面底部穿透到屏幕底部导航栏(小横条)背后的问题

A:请关闭这个设置:

//使用沉浸式适配
//请注意,若你没有使用沉浸式适配,请关闭此选项,此选项将影响对话框布局是否允许延伸至导航栏背后显示
DialogX.useActivityLayoutTranslationNavigationBar = false;

详细原因:

因为 fitSystemWindow 标记只能对一个 Window 下的一个 View 生效,DialogX 要是自己用了用户那边就没法用,所以 DialogX 不能 Hook 这个标记,DialogX是在DialogXBaseRelativeLayout 这个布局组件中处理沉浸式相关事务的,包括键盘弹起,这都算底部非安全区高度变化相关逻辑,但 Google 在针对未设置此 Flag 的情况下,会出现弹出新对话框时,旧对话框(已弹出的其他对话框)接收到一次异常的底部高度变化值,其特征是会出现先归0然后回调几次后再恢复正常的值,表现形式是涉及底部显示的对话框出现“弹跳”的问题。

为解决这个问题,DialogX 的最新版本默认启用了对 Window 设置 SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION 标记的操作,若需要关掉它请使用:

DialogX.useActivityLayoutTranslationNavigationBar = false;

Q:DialogX 无法覆盖在 DialogFragment、AlertDialog 之上

A:DialogX 默认使用 View 实现方式,你可以理解为实际上只是在当前 Activity 上叠加了一层 DialogView,因为并不是独立的 Window,所以无法覆盖在 DialogFragment、AlertDialog 之上。

我们更推荐您将使用 DialogFragment、AlertDialog 方案实现的对话框,改为 DialogX 替代,DialogX 也提供了诸如 CustomDialog 这样的组件以满足个性化对话框的需要。

若实在无法替代,您可以尝试 [DialogX 的其他实现模式](https://github.com/kongzue/DialogX/wiki#%E5%AE%9E%E7%8E%B0%E6%A8%A1%E5%BC%8F),但请谨慎使用,其他方案依然存在特定情况下的 bug,若你有遇到,请反馈给我们。


Q:在 BottomDialog 和 FullScreenDialog 对话框中让自己的滑动布局支持滑动继承

A:直接滑动 BottomDialog 和 FullScreenDialog 对话框中的 ScrollView、ListView、RecycleView 等布局可能无法实现和对话框下滑关闭的联动,要实现此功能,请自定义对应的组件,继承 ScrollController,并完成以下接口的实现:

@Override
//请按照固定写法
public boolean isLockScroll() {
    return lockScroll;
}

boolean lockScroll;

@Override
//请按照固定写法
public void lockScroll(boolean lockScroll) {
    this.lockScroll=lockScroll;
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    if (lockScroll) return false;
    return super.onTouchEvent(event);
}

@Override
//获取已滚动距离,请注意不同组件的获取方式不同,请按照根据实际情况调整
public int getScrollDistance() {
    return getScrollY();
}

@Override
//固定写法
public boolean isCanScroll() {
    return true;
}

然后在对需要继承滑动的布局设置 Tag,固定文本“ScrollController”,BottomDialog 和 FullScreenDialog 对话框会在运行后识别子布局中的 ScrollController 实现,并在其处于滑动到顶部且继续下滑时接管触摸事件。


Q:重写 Activity 的 onKeyDown 里弹出对话框无效/对话框的不拦截返回?

A:因为 Activity 的 onKeyDown 属于事件链的上游,此时对话框未启动或 KeyBack 事件还未传递到对话框,对话框无法进行处理,请使用 onBackPressed 处理,例如:

@Override
public void onBackPressed() {
    MessageDialog.show("提示", "确认退出?", "是", "否")
            .setOkButton(new OnDialogButtonClickListener<MessageDialog>() {
                @Override
                public boolean onClick(MessageDialog baseDialog, View v) {
                    MainActivity.super.onBackPressed();
                    return false;
                }
            });
}

Q:如何修改圆角?如何修改某个组件的背景样式?如何单独修改某个对话框的背景样式?

A:请参考 issues:228


Q:如何实现传统的进度条对话框?

A:请参考 利用DialogX实现传统进度条对话框效果

image


Q:如何复用一个对话框?

A:DialogX 建议对话框的使用是单次的,这意味着当你对一个已经显示的对话框执行 .dismiss() 方法时将完全销毁它,这是为了避免内存占用和内存泄漏,要重复使用一个对话框保留其状态(例如其中有用户交互输入的内容或自定义布局进行了操作),首先请在对话框启动时拿到其对象实例:

//在全局设置一个对话框实例
private InputDialog inputDialog;
//显示对话框并获取其实例
inputDialog = InputDialog.show("这是一个输入框","输入提示文本","OK","CANCEL")

接着编写其相关事件处理:

inputDialog = InputDialog.show("这是一个输入框","输入提示文本","OK","CANCEL")
        .setOkButton(new OnInputDialogButtonClickListener<InputDialog>() {
            @Override
            public boolean onClick(InputDialog dialog, View v, String inputStr) {
                //使用退出动画隐藏对话框
                dialog.hideWithExitAnim();
                //return true 拦截 OK 按钮点击不要自动 dismiss
                return true;
            }
        })
        .setCancelButton(new OnInputDialogButtonClickListener<InputDialog>() {
            @Override
            public boolean onClick(InputDialog dialog, View v, String inputStr) {
                dialog.hideWithExitAnim();
                //return true 拦截 Cancel 按钮点击不要自动 dismiss
                return true;
            }
        })
        .setOnBackgroundMaskClickListener(new OnBackgroundMaskClickListener<MessageDialog>() {
            @Override
            public boolean onClick(MessageDialog dialog, View v) {
                dialog.hideWithExitAnim();
                //return true 拦截背景遮罩点击不要自动 dismiss
                return true;
            }
        })
        .setOnBackPressedListener(new OnBackPressedListener<MessageDialog>() {
            @Override
            public boolean onBackPressed(MessageDialog dialog) {
                dialog.hideWithExitAnim();
                //return true 拦截返回键点击不要自动 dismiss
                return true;
            }
        });

要重新显示这个对话框,可以直接使用 .show() 命令:

inputDialog.show();

理论上在 activity 销毁时 DialogX 也会自行销毁对应该 activity 的对话框,若你担心,可以在 activity#onDestroy() 中加入手动销毁的方法:

inputDialog.dismiss();

ℹ️Issues经典问题

【功能建议】可以让BottomMenu 支持显示多行吗? 而不是超过1行 后面就点点点

popmenu如果挂点的view在边缘的话,弹出来的popmenu会变形

当前页面dialog跑到上个页面显示

Clone this wiki locally