【问题标题】:WindowManager.addView ontop(overlay) of soft key OR nav barWindowManager.addView ontop(overlay) of soft key OR nav bar
【发布时间】:2015-02-25 13:48:13
【问题描述】:

我今天看到一个覆盖整个屏幕的应用程序,包括导航栏(或具有返回、主页等的软键)。它是链火的 CF.Lumen(需要 android 4.4+)。

我只记得这在一般方法上是不可能的,许多 SO 答案告诉我。所以我从 Lumens apk(sorry chainfire) 中查看了 smali 代码,发现 0x7d6 作为类型说明符,即 TYPE_SYSTEM_OVERLAY。 通常,这会使视图覆盖在锁定屏幕的顶部。它看起来不错,但不会覆盖导航栏区域。即使在锁定屏幕上。 我确实将MATCH_PARENT 替换为9999,但它仍然不会覆盖导航栏区域。

我查看了Android的源代码,发现有更多类型未记录的有趣。

FIRST_SYSTEM_WINDOW = 2000;

TYPE_NAVIGATION_BAR = FIRST_SYSTEM_WINDOW+19;

TYPE_BOOT_PROGRESS = FIRST_SYSTEM_WINDOW+21;

我将这些应用到我的应用程序中,但崩溃说权限被拒绝。它需要INTERNAL_SYSTEM_WINDOW 或比SYSTEM_ALERT_WINDOW 更无证的东西。这些权限仅授予系统应用程序。

这是我添加视图的代码,该视图填充了除导航栏区域之外的整个屏幕。

我应该怎么做才能完成它?(使覆盖包括导航栏区域)

final WindowManager.LayoutParams paramsRL = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.MATCH_PARENT,
            WindowManager.LayoutParams.MATCH_PARENT,
            WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
            WindowManager.LayoutParams.FLAG_FULLSCREEN
                    | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
                    | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                    | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                    | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
                    | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
            PixelFormat.TRANSLUCENT);
windowManager.addView(view_floating, paramsRL);

【问题讨论】:

  • TYPE_PHONE 还不够吗?
  • TYPE_PHONETYPE_PRIORITY_PHONE 甚至在锁定屏幕上也不会覆盖。

标签: android overlay android-view android-windowmanager android-layoutparams


【解决方案1】:

这是一个有效的小例子:

    FrameLayout frameLayout = new FrameLayout(context);
    frameLayout.setBackgroundColor(Color.BLACK);
    frameLayout.setAlpha(0.5f);

    windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    WindowManager.LayoutParams params = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.MATCH_PARENT,
            WindowManager.LayoutParams.MATCH_PARENT,
            WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
            WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
                    | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                    | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED
                    | WindowManager.LayoutParams.FLAG_FULLSCREEN
                    | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
            PixelFormat.TRANSLUCENT);

    //make sure height includes the nav bar size (get the dimension of whole screen)
    params.height = screenHeight;
    params.width = screenWidth;
    windowManager.addView(frameLayout, params);

    //add your view to this frameLayout
    frameLayout.addView(....);

这里的三个关键点是:

  1. TYPE_SYSTEM_OVERLAY(或任何类似类型)可以在整个屏幕上显示内容。

  2. FLAG_LAYOUT_NO_LIMITS 允许我们超过允许的正常大小。

  3. 设置需要在软键后面覆盖的额外高度。主要问题是当我们将参数设置为 match_parent 时,它设置为屏幕高度减去我想的导航栏。设置额外的高度可以解决问题。

【讨论】:

  • 而且也不覆盖操作栏。
【解决方案2】:

不要使用WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,这个标志会让导航栏一直显示。我不知道为什么。

【讨论】:

  • 好的答案应该有完整的解释。做一些探索,找出你的解决方案为什么有效。当您在此处共享该信息时。尝试将 Stack Overflow 更多地视为社区驱动的技术问题/解决方案库,而不是为寻求快速解决他们无法修复的错误的人们提供的聊天论坛。
猜你喜欢
  • 2022-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-12
相关资源
最近更新 更多