【问题标题】:Overlay Status bar on android 4.2.2+android 4.2.2+ 上的覆盖状态栏
【发布时间】:2014-09-12 14:25:05
【问题描述】:

我想覆盖android状态栏。就我而言,它位于顶部。我不想覆盖或隐藏导航栏。

注意:解决方案必须适用于 android 4.2.2+。我更喜欢非根设备的答案。

我搜索了许多 SO 问题和答案,但没有一个适用于 4.2.2。

下面是我的代码,但它不消耗触摸事件。这就是状态栏打开其面板的原因。我不想要这个。

@Override 
public void onCreate() {
    super.onCreate();

    windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);

    int statusBarHeight = (int) Math.ceil(25 * getResources().getDisplayMetrics().density);

    overlay = new Button(this);
    overlay.setBackgroundColor(Color.GREEN);
    overlay.setOnTouchListener(new OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            Log.i("StatusBar", "touched");
            return false;
        }
    });

    WindowManager.LayoutParams params = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.FILL_PARENT,
            statusBarHeight,
            WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|
            WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL|
            WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH|
            WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
            PixelFormat.TRANSLUCENT);

    params.gravity = Gravity.TOP | Gravity.RIGHT;

    windowManager.addView(overlay, params);

}

@Override
public void onDestroy() {
    super.onDestroy();
    if (overlay != null) windowManager.removeView(overlay);
}

在主要活动中我开始服务:

startService(new Intent(this, StatusBarService.class));

并在AndroidManifest.xml中添加权限:

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

现在证明它可以完成并且它适用于 4.2.2: Play Google - MobiLock

怎么做?

截图:

【问题讨论】:

  • 请提供一些你想要实现的截图/图片
  • @JiMMaR:最好的可视化方式是安装并运行 MobiLock 启动器。留意他们的自定义状态栏。即使您在启动器中运行允许的应用程序之一,它也保持不变。
  • 已添加@JiMMaR 截图

标签: android android-ui statusbar android-4.2-jelly-bean android-launcher


【解决方案1】:

在尝试&重复之后,这为我做到了:

int statusBarHeight = (int) Math.ceil(25 * getResources().getDisplayMetrics().density);

WindowManager.LayoutParams params = new WindowManager.LayoutParams(WindowManager.LayoutParams.FILL_PARENT,
            statusBarHeight,
            WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|
            WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL|
            WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
            PixelFormat.TRANSLUCENT);

它适用于 4.2.2 和 4.4.2

【讨论】:

  • 嗨@Solata,我对你没有任何个人意见。感谢您的澄清。我也会投票赞成你的答案。答案也有很好的解释。通常 Stackoverflow 包含很多用户只是为了制作这样的配置文件。至于我的名声,我不在乎。我不是来这里有好名声的,我一般不会只看40K以上用户的帖子。有很多人知识渊博,给出了很好的答案,但在这里没有很好的声誉。
  • @AzatMartirosyan:我喜欢你关心这个,但你的方法不行。 Stackoverflow 有非常好的 QA 评级流程来避免这种非建设性的评论..
  • statusBarHeight 应该使用什么值?
【解决方案2】:

我们无法阻止在 kitkat 设备中以全屏模式显示状态,所以做了一个仍然符合要求的 hack,即阻止状态栏扩展。

为此,该应用并未全屏显示。我们在状态栏上放置了一个覆盖层并消耗了所有输入事件。它阻止了状态扩展。

注意:

  • customViewGroup 是自定义类,它扩展了任何 布局(框架,相对布局等)并消耗触摸事件。
  • 消费触摸事件覆盖onInterceptTouchEvent方法 视图组并返回 true

更新

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> 

customViewGroup implementation 代码:

WindowManager manager = ((WindowManager) getApplicationContext()
            .getSystemService(Context.WINDOW_SERVICE));

WindowManager.LayoutParams localLayoutParams = new WindowManager.LayoutParams();
localLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
localLayoutParams.gravity = Gravity.TOP;
localLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|

            // this is to enable the notification to recieve touch events
            WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |

            // Draws over status bar
            WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;

    localLayoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
    localLayoutParams.height = (int) (50 * getResources()
            .getDisplayMetrics().scaledDensity);
    localLayoutParams.format = PixelFormat.TRANSPARENT;

    customViewGroup view = new customViewGroup(this);

    manager.addView(view, localLayoutParams);

注意不需要root

【讨论】:

  • 昨天这对我有用,但由于某种原因今天不行......我无法让它恢复工作。我用的代码和你贴的一模一样。
  • 我无法提供上述详细信息。
  • @Machado 如果你能解释一下你所做的一切我可以帮助你
【解决方案3】:

你不能把你的应用程序放在一个 notitlebar 主题中[不应该删除导航栏],并在顶部实现你自己的视图,模仿通知栏的外观作为容器,其余内容将是片段?

【讨论】:

  • 这在启动器的主要形式位于顶部时有效。但如果启动另一个应用程序,状态栏会再次显示。我设法用 StatusBarService.class 隐藏状态栏。但是触摸事件在后台被转发到状态栏。所以用户可以向下滑动状态面板。
猜你喜欢
  • 1970-01-01
  • 2016-12-21
  • 2021-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多