如何保持对话框中的沉浸模式?

2023-11-25

当我的活动显示自定义对话框时,如何维护新的沉浸模式?

我使用下面的代码来维护对话框中的沉浸模式,但是使用该解决方案,当我启动自定义对话框时,导航栏会出现不到一秒钟,然后就会消失。

以下视频更好地解释了该问题(当导航栏出现时,请查看屏幕底部):http://youtu.be/epnd5ghey8g

我该如何避免这种行为?

CODE

我的应用程序中所有活动的父亲:

public abstract class ImmersiveActivity extends Activity {

    @SuppressLint("NewApi")
    private void disableImmersiveMode() {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
            getWindow().getDecorView().setSystemUiVisibility(
                    View.SYSTEM_UI_FLAG_FULLSCREEN
            );
        }
    }

    @SuppressLint("NewApi")
    private void enableImmersiveMode() {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
            getWindow().getDecorView().setSystemUiVisibility(
                      View.SYSTEM_UI_FLAG_LAYOUT_STABLE 
                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION 
                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 
                    | View.SYSTEM_UI_FLAG_FULLSCREEN 
                    | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY 
                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
            );
        }
    }


    /**
     * Set the Immersive mode or not according to its state in the settings:
     * enabled or not.
     */
    protected void updateSystemUiVisibility() {
        // Retrieve if the Immersive mode is enabled or not.
        boolean enabled = getSharedPreferences(Util.PREF_NAME, 0).getBoolean(
                "immersive_mode_enabled", true);

        if (enabled) enableImmersiveMode();
        else disableImmersiveMode();
    }

    @Override
    public void onResume() {
        super.onResume();
        updateSystemUiVisibility();
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        updateSystemUiVisibility();
    }

}


我所有的自定义对话框都在其调用此方法onCreate(. . .) method:

/**
 * Copy the visibility of the Activity that has started the dialog {@link mActivity}. If the
 * activity is in Immersive mode the dialog will be in Immersive mode too and vice versa.
 */
@SuppressLint("NewApi")
private void copySystemUiVisibility() {
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
        getWindow().getDecorView().setSystemUiVisibility(
                mActivity.getWindow().getDecorView().getSystemUiVisibility()
        );
    }
}


编辑 - 解决方案(感谢 Beaver6813,请查看他的答案以获取更多详细信息):

我的所有自定义对话框都以这种方式重写 show 方法:

/**
 * An hack used to show the dialogs in Immersive Mode (that is with the NavBar hidden). To
 * obtain this, the method makes the dialog not focusable before showing it, change the UI
 * visibility of the window like the owner activity of the dialog and then (after showing it)
 * makes the dialog focusable again.
 */
@Override
public void show() {
    // Set the dialog to not focusable.
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);

    copySystemUiVisibility();

    // Show the dialog with NavBar hidden.
    super.show();

    // Set the dialog to focusable again.
    getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
}

经过对这个问题的大量研究后,有一个解决这个问题的办法,其中包括撕开Dialog类来查找。将对话框窗口添加到窗口管理器时,即使您在将其添加到管理器之前设置了 UI 可见性,也会显示导航栏。在里面Android 沉浸式示例评论说:

// * Uses semi-transparent bars for the nav and status bars
// * This UI flag will *not* be cleared when the user interacts with the UI.
// When the user swipes, the bars will temporarily appear for a few seconds and then
// disappear again.

我相信这就是我们在这里看到的(当一个新的、可聚焦的窗口视图添加到管理器时,将触发用户交互)。

我们如何解决这个问题?在创建对话框时使其不可聚焦(这样我们就不会触发用户交互),然后在显示后使其可聚焦。

//Here's the magic..
//Set the dialog to not focusable (makes navigation ignore us adding the window)
dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);

//Show the dialog!
dialog.show();

//Set the dialog to immersive
dialog.getWindow().getDecorView().setSystemUiVisibility(
context.getWindow().getDecorView().getSystemUiVisibility());

//Clear the not focusable flag from the window
dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);

显然这并不理想,但这似乎是一个 Android 错误,他们应该检查窗口是否有沉浸式设置。

我已经更新了我的工作测试代码(请原谅混乱的情况)Github。我已经在 Nexus 5 模拟器上进行了测试,它可能会在奇巧之外的任何东西上爆炸,但它仅用于概念验证。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何保持对话框中的沉浸模式? 的相关文章

  • 如何为 Android 创建我们自己的 PDF 查看器?

    我想构建一个可在我的 Android 应用程序中使用的 PDF 阅读器 查看器 但我无法使用 Google 文档来阅读我的内容 我无法使用我的设备中已安装的任何 PDF 阅读器 它应该位于我的应用程序内 并且不会通过互联网公开我的安全内容
  • 什么是适合 Android 的 html 解析器?

    什么是适合 Android 的 html 解析器 这取决于你想做什么 如果你真的想处理 html Java 中有很多 html 解析器可以使用 这里有一些 https stackoverflow com questions 2168610
  • 如何自定义 Firebase 身份验证 ui

    我正在使用 Firebase Auth Ui 进行号码验证 我有一些要求 需要更改国家旋转器下拉项目的文本和背景颜色 我正在使用下面的样式 但它不会改变下拉菜单的背景颜色或项目的文本颜色 style name FirebaseUI Coun
  • 在 Android 模拟器上运行完整的 Android 手机 ROM

    正如标题所说 是否可以在 Android 模拟器中运行完整的 Android 设备 ROM 是的 你可以 但让它 100 工作可能很困难 大多数 ROM 都包含其运行硬件的特定驱动程序 我并不是 100 全力以赴 但可以尝试以下步骤 创建
  • Android Toast 消息不起作用

    我正在通过 Andengine 为 Android 开发游戏 我有 MainActivity 类和 GameScene 类 我在 GameActivity 中使用 Toast 消息 它正在发挥作用 Toast makeText this H
  • 禁用 com.google.android.maps.MapView 中的平移/缩放

    如何禁用 MapView 的平移 缩放功能 不是缩放控件 我想要一个完全静态的地图 我还注意到触摸地图似乎不会触发 MapView onClickListener 有人可以详细说明为什么吗 对于 Android 版 Google Maps
  • Android 位置 API:获取提供商状态

    在 Android 中获取位置提供商状态的最佳方式是什么 当注册 LocationListener 以进行位置更新时 onStatusChanged String provider int status Bundle extras 每当状态
  • Android:将声音保存为铃声/SQLiteConstraintException

    我正在尝试使用 Android 将声音保存为铃声this http www stealthcopter com blog 2010 01 android saving a sound file to sd from resource and
  • 为什么我的地图视图上的叠加层没有显示?

    我按照 google hellomapview 教程中的说明进行操作 我得到了一个工作地图视图等 但是添加到地图中的两个项目没有显示 它们似乎在某个地方 因为点击指定位置会显示添加到项目中的消息 Edit 这是我的源代码 应该和google
  • NDK8d 未找到 std::string 操作(即 stol、stoi)

    我尝试使用 ndk r8d 和 c 11 支持来建立我的第一个 android 项目 一些 c 11 机制工作正常 即 lambda 表达式 但是当我尝试时 使用新的字符串操作之一 编译失败 错误 stol 不是 std 的成员 这是我的
  • eglCodecCommon:setVertexArrayObject:设置vao调试消息

    我的 Android Emulator API 28 logcat 被这样的消息搞得晕头转向 D eglCodecCommon setVertexArrayObject set vao to 1 1 0 0 D eglCodecCommon
  • 如何将AVFrame转换为glTexImage2D使用的纹理?

    如您所知 AVFrame 有 2 个属性 pFrame gt data pFrame gt linesize 当我从视频 sdcard test mp4 android平台 读取帧后 并将其转换为RGB AVFrame副 img conve
  • Proguard 正在破坏我的清洁度。 Gson 和泛型

    我有一个从持久性加载信息的函数 我只是以一种非常简单的方式告诉它的类型 该类称为SharedPreferencesHelper kt所以它是一个真正的生活问题解决者 fun
  • 线性布局高度和重量

    我有以下内容
  • 无法使用 Zxing Android 扫描 Code 128

    我已将 ZXing 条码阅读器集成到我的 Android 应用程序中 它可以扫描大部分代码 但我有一张电费单 它无法扫描 使用 Galaxy Ace 5 0MP 我认为问题是由于相机分辨率和焦点造成的 因为当我使用 Xperia SL 12
  • Android:是否可以在可绘制选择器中使用字符串/枚举?

    问题 Q1 有人设法让自定义字符串 枚举属性在 xml 选择器中工作吗 我通过以下 1 获得了一个布尔属性 但不是字符串属性 编辑 感谢您的回答 目前 android 仅支持布尔选择器 原因请参阅已接受的答案 我计划实现一个复杂的自定义按钮
  • Firebase:用户注册后如何进行电话号码验证?

    所以我知道我可以使用电子邮件验证或电话号码验证 但我想做的是在用户注册或登录后进行电话号码验证 如何连接这两种身份验证方法 最后 Firebase中是否有一个函数可以检查用户是否通过电话号码验证 谢谢 即使用户已通过身份验证 您仍然可以使用
  • 使用bindService启动IntentService时是否应该调用onHandleIntent?

    我的服务延伸IntentService当它开始时startService onHandleIntent被叫 但是 当服务启动时bindService 我确实需要绑定 onHandleIntent没有被调用 Should onHandleIn
  • 永久删除Android文件

    我发现了一个名为这会从 Android 设备中永久删除文件和文件夹 以便删除的文件无法再恢复 这是我正在谈论的应用程序 但我想知道如何做到这一点 我知道它是用 android studio 制作的 i尝试了常规的删除方式file delet
  • 使用部分字符串匹配进行 Firebase 查询[重复]

    这个问题在这里已经有答案了 假设我有一个简单的 firebase 实时数据库结构 其中关键是username其值为userid 现在我想搜索userid by username 如果用户名匹配 这很容易 但如何获得部分匹配的答案 更清楚地说

随机推荐

  • 预加载图像

    有没有办法只使用 html css 预加载图像 是的你可以 有很多关于这个主题的教程 这是其中之一
  • C# 代码中 where 子句的混淆

    public interface ICrudService
  • Google PlusOne 按钮在 Chrome 上出现错误

    Google PlusOne 在 Chrome 上出现错误 Uncaught ReferenceError iframes is not defined fastbutton 19 Uncaught ReferenceError ifram
  • 如何使用 window.open 设置文件名

    我正在尝试下载由 JavaScript 计算的临时结果 假设我有一个字符串str 我想下载一个文件包含str并将其命名为data csv 我使用以下代码 window open data text csv charset utf 8 str
  • 多线程环境下的文件访问策略(Web App)

    我有一个文件 它是从 Web 服务获取并在 Web 应用程序中本地缓存的一些数据的 XML 表示形式 这个想法是这个数据是very静态的 但只是might改变 因此 我将其设置为缓存到一个文件 并在其上放置一个监视器以检查它是否已被删除 删
  • C# 使用 System.Linq 错误

    为什么 使用 System Linq 可能会导致以下错误 类型或命名空间名称 Linq 确实 命名空间 System 中不存在 参考System Core 然后还有其他人也合并了这个命名空间 但这是主要的在 Net 3 5 及更高版本上 如
  • ADT 插件无法安装:缺少要求:Android 开发工具

    我尝试在 eclipse helios windows 64 位经典上安装 ADT 插件 我收到这个错误 无法完成安装 因为找不到一项或多项所需的项目 正在安装的软件 Android开发工具16 0 1 v201112150204 2385
  • SQL Server 将字符串转换为日期时间

    这并不是询问如何在 MSSQL 中将任意字符串转换为日期时间 例如这个问题 我可以控制字符串格式 但我想知道使用日期字符串更新日期时间字段的 MSSQL 语法是什么 UPDATE MyTable SET MyDate CONVERT dat
  • PDO 更新不替换准备好的语句中的占位符[重复]

    这个问题在这里已经有答案了 我正在尝试使用以下代码更新表格 如果我改变WHERE temp booking id temp booking id 使用实际的当前会话temp id 查询将运行 但将占位符添加到表中 例如 签出 作为值 dat
  • 使用huggingface Trainer 与分布式数据并行

    为了加快性能 我研究了 pytorch分布式数据并行并尝试将其应用于变压器Trainer The DDP 的 pytorch 示例指出这应该at least更快 DataParallel是单进程 多线程 只能在单机上运行 而Distribu
  • 我需要获取我的 firebase 数据库的最后一个子项

    i want to get last child from my firebase data structure in which i only know the reference of received and first child
  • Go 模块拉取旧版本的包

    我正在尝试使用 go 模块将新包添加到我的项目中 该包使用 github com docker docker client 并且在项目之外运行良好 当我跑步时go mod vendor它拉取版本 v1 13 1 的 docker 客户端包
  • 以非多态方式调用虚函数的成本是多少?

    我有一个纯抽象基类和两个派生类 struct B virtual void foo 0 struct D1 B void foo override cout lt lt D1 foo lt lt endl struct D2 B void
  • 如何在 Ubuntu 中的 Visual Studio Code 上开发(运行和调试)Odoo v11 模块?

    是否可以在 Visual Studio Code 上运行和调试 Odoo 如果是 请分享我的配置 视觉工作室代码是 Microsoft 为 Windows Linux 和 macOS 开发的源代码编辑器 它包括对调试 嵌入式 Git 控制
  • 如何在 AS3 中创建自定义 MouseEvent.CLICK 事件(将参数传递给函数)?

    这个问题不仅与 MouseEvent CLICK 事件类型有关 而且与 AS3 中已存在的所有事件类型有关 我阅读了很多有关自定义事件的内容 但直到现在我还不知道如何做我想做的事情 我将尝试解释一下 希望您能理解 这是我的情况的说明 for
  • 使用 ifort 进行数组复制时程序崩溃

    这个程序崩溃了Illegal instruction 4在 MacOSX Lion 和 ifort IFORT 12 1 0 20111011 上 program foo real pointer a b allocate a 5400 5
  • 在画布中拖动时图像闪烁

    我正在画布中拖动图像 但在拖动过程中图像会闪烁 我认为函数调用存在一些问题 我已经实现了 onmousedown onmouseup 和 onmousemove 事件的功能 我在拖动过程中将图像绘制到画布上 这是我的代码 div div
  • 如何在 C++ 中重复字符串多次?

    我想在 C 中的字符串开头插入 n 个空格 或任何字符串 有没有直接的方法可以使用 std strings 或 char 字符串来执行此操作 例如 在 Python 中你可以简单地做 gt gt gt 5 lolcat lolcat 在重复
  • 如何获取进程ID来杀死nohup进程? [关闭]

    Closed 这个问题是与编程或软件开发无关 目前不接受答案 我正在服务器上运行 nohup 进程 当我尝试杀死它时 我的腻子控制台会关闭 这是我尝试查找进程 ID 的方法 ps ef grep nohup 这是杀死命令 kill 9 17
  • 如何保持对话框中的沉浸模式?

    当我的活动显示自定义对话框时 如何维护新的沉浸模式 我使用下面的代码来维护对话框中的沉浸模式 但是使用该解决方案 当我启动自定义对话框时 导航栏会出现不到一秒钟 然后就会消失 以下视频更好地解释了该问题 当导航栏出现时 请查看屏幕底部 ht