如何在 Android 中创建始终位于顶部的全屏覆盖活动
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10095344/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to create always-top fullscreen overlay activity in Android
提问by tmouse
I'd like to be able to create an Activity that is always at the front of display of Android. It should receive no input, just pass it down to whatever application is next below it. Something like a HUD.
我希望能够创建一个始终位于 Android 显示屏前面的活动。它不应该接收任何输入,只需将其传递给它下面的任何应用程序。类似HUD的东西。
I was able to research that I need to set underlying window type to TYPE_SYSTEM_ALERT but it looks like Android is ignoring my code - no exception thrown even if I delete android.permission.SYSTEM_ALERT_WINDOW permission from manifest. (it is required to use this window type). When I tried to use ALERT type on dialog, it worked OK, but I cannot make dialog into full screen transparent entity. Here is my code, maybe there is something simple missing.
我能够研究我需要将底层窗口类型设置为 TYPE_SYSTEM_ALERT 但看起来 Android 正在忽略我的代码 - 即使我从清单中删除 android.permission.SYSTEM_ALERT_WINDOW 权限也不会抛出异常。(需要使用这种窗口类型)。当我尝试在对话框上使用 ALERT 类型时,它工作正常,但我无法将对话框设为全屏透明实体。这是我的代码,也许缺少一些简单的东西。
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
getWindow().setBackgroundDrawableResource(android.R.color.transparent);
getWindow().setFormat(PixelFormat.TRANSLUCENT);
setContentView(R.layout.main);
}
Translucent setting has to be enabled externally in xml manifest, otherwise it also didn't work.
半透明设置必须在 xml manifest 中从外部启用,否则它也不起作用。
<item name="android:windowIsTranslucent">true</item>
回答by tmouse
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
PixelFormat.TRANSLUCENT);
WindowManager wm = (WindowManager) getApplicationContext()
.getSystemService(Context.WINDOW_SERVICE);
ViewGroup mTopView = (ViewGroup) App.inflater.inflate(R.layout.main, null);
getWindow().setAttributes(params);
wm.addView(mTopView, params);
回答by Birchlabs
I found that the accepted answer (by tmouse)did not quite work for me. Maybe it worked for an older API level? I'm using API level 24.
我发现接受的答案(由 tmouse 提供)对我来说不太适用。也许它适用于较旧的 API 级别?我正在使用 API 级别 24。
That particular answer had recommended:
该特定答案建议:
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
PixelFormat.TRANSLUCENT
);
There is a problem with this. The constructors that exist for WindowManager.LayoutParams
are as follows:
这有问题。存在的构造函数WindowManager.LayoutParams
如下:
So the WindowManager.LayoutParams.FLAG_FULLSCREEN
flag gets used as an explicit value for int w
and int h
. This is no good! Your view's dimensions get set to 1024*1024 — so it does not fillthe screen. And even if you explicitlyset the layout's width and height to match the device's dimensions: they will notupdate when the screen orientation changes. We need a different approach…
因此该WindowManager.LayoutParams.FLAG_FULLSCREEN
标志被用作and的显式值int w
int h
。这不好!你的视图尺寸被设置为 1024*1024——所以它不会填满屏幕。即使您明确设置布局的宽度和高度以匹配设备的尺寸:当屏幕方向改变时,它们也不会更新。我们需要一种不同的方法……
I found that the correctconstruction for a full-screen overlay is like so:
我发现全屏覆盖的正确构造是这样的:
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, // TYPE_SYSTEM_ALERT is denied in apiLevel >=19
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_FULLSCREEN,
PixelFormat.TRANSLUCENT
);
This means we no longer explicitlyspecify a width and height. The layout relies entirely on our flags instead.
这意味着我们不再明确指定宽度和高度。布局完全依赖于我们的标志。
Yes, WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
is a required flag still; it is necessary if you want to draw over decorations such as the status bar.
是的,WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
仍然是必需的标志;如果要绘制状态栏等装饰,则有必要。
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY
should be used instead of TYPE_SYSTEM_ALERT
in API level >=19. This is a note I wrote a while ago, sadly I've been unable to find citation to corroborate why I thought that, so take that with a pinch of salt.
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY
应该TYPE_SYSTEM_ALERT
在 API 级别 >=19 中使用而不是使用。这是我不久前写的一篇笔记,遗憾的是我一直无法找到引文来证实我为什么这么认为,所以请加一点盐。
Bonus notes (if you're reading this, you're probably trying to make a full-screen overlay):
附注(如果您正在阅读本文,您可能正在尝试制作全屏叠加):
Your manifest will need these permissions (explanation here):
您的清单将需要这些权限(此处解释):
<uses-permission android:name="android.permission.ACTION_MANAGE_OVERLAY_PERMISSION"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
My understanding is that SYSTEM_ALERT_WINDOW
is the actual permission required, but that ACTION_MANAGE_OVERLAY_PERMISSION
is needed also: it lets you request at runtime that the user grant the SYSTEM_ALERT_WINDOW
privilege.
我的理解是这SYSTEM_ALERT_WINDOW
是所需的实际权限,但这ACTION_MANAGE_OVERLAY_PERMISSION
也是必需的:它允许您在运行时请求用户授予SYSTEM_ALERT_WINDOW
权限。
I provide herethe source code to my working API level 24 app that creates a full-screen overlay.
我在这里提供了我的工作 API 级别 24 应用程序的源代码,该应用程序创建了一个全屏覆盖。
回答by Ravi1187342
Check out this
看看这个
mention it in your AndroidManifest.xml file
在您的 AndroidManifest.xml 文件中提及它
<activity android:name=".MyActivity" android:theme="@android:style/Theme.NoTitleBar.Fullscreen" />
if you want to make your Activity full screen and transparent also
如果你想让你的 Activity 也全屏和透明
check out this
看看这个
<activity android:name=".MyActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen" />