我正在尝试在锁屏上显示视图,并希望能够部分显示它(例如,当视图处于“非活动状态”时,视图的一半在屏幕外)。 br />对于here和here所述类型WindowManager.LayoutParams.TYPE_SYSTEM_ERROR
(以及其他一些建议使用此标志的帖子),我可以在锁屏上显示它。但是与标志WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
一起似乎不适用于API级别21。
代码:
WindowManager.LayoutParams params = new
WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH |
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, PixelFormat.TRANSPARENT);
但经过一些测试后,WindowManager.LayoutParams.TYPE_SYSTEM_ERROR
类型和旗帜WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
的组合在Android API级别16上有效,但在第21级无效。它只是保持边缘的一侧而不会脱落-屏幕。我也试过设置horizontalmargin属性,但没有用。
结果不同:
添加视图的代码(精简版):
layout = (RelativeLayout) getLayoutInflater().inflate(R.layout.testlayout, null).findViewById(R.id.rl);
params = new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_SYSTEM_ERROR, WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, PixelFormat.TRANSPARENT);
params.x = 600;
manager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
manager.addView(layout, params);
这是一个错误还是其他什么?有没有解决方法,如果有的话?
这两个屏幕具有相同的尺寸,分辨率和密度吗?
分辨率是,尺寸号,密度也没有。
如果稍微增加水平偏移量(
params.x
值),那么apis 16和21都会向右移动吗?
在API级别16上它向右移动了一点,但是在21级它只是保持在右侧并且什么都不做。
更新
我看过另一款应用,他们能够实现这一目标(参见this gif)。我反编译他们的apk看看他们的源代码,我发现有关LayoutParams的唯一方法是:
private LayoutParams getLayoutParams() {
LayoutParams params = new LayoutParams(WRAP_CONTENT, WRAP_CONTENT, this.lockscreen ? 2010 : 2002, 262696, -3);
if (this.focusable) {
params.flags ^= 8;
}
params.gravity = 8388659;
if (this.keyboard) {
params.softInputMode = 16;
}
return params;
}
this.lockscreen
是一个布尔值,它是否应显示在锁屏上
2010
是WindowManager.LayoutParams.TYPE_SYSTEM_ERROR
(https://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#TYPE_SYSTEM_ERROR)
2002
是WindowManager.LayoutParams.TYPE_PHONE
,
试过这个并且不能在锁屏(https://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#TYPE_PHONE)左
262696
flags = 0x40228
= FLAG_WATCH_OUTSIDE_TOUCH, FLAG_LAYOUT_NO_LIMITS, FLAG_NOT_TOUCH_MODAL, FLAG_NOT_FOCUSABLE
-3
是PixelFormat.TRANSLUCENT
(https://developer.android.com/reference/android/graphics/PixelFormat.html#TRANSLUCENT)
所以我真的很想知道他们是如何实现这一点的,因为他们似乎也使用了类型WindowManager.LayoutParams.TYPE_SYSTEM_ERROR
。
答案 0 :(得分:2)
这可能是不可能的......
我发现了blog post:
在Android 4.4中,此行为已更改。实际上,此更改会禁用
FLAG_LAYOUT_NO_LIMITS
Windows的TYPE_SYSTEM_ERROR
。这使得用户应用程序无法再在显示的导航栏上放置窗口。
引用此Android source code commit。提交消息指出:
Limit TYPE_SYSTEM_ERROR to system decor bounds.
Because windows of TYPE_SYTEM_ERROR lie in a layer above the
Navigation Bar they cannot be allowed to extend into the Navigation
Bar area or it will block touches to the Home button.
Fixes bug 9626315
和一段差异显示:
- if ((fl & FLAG_LAYOUT_NO_LIMITS) != 0) {
+ // TYPE_SYSTEM_ERROR is above the NavigationBar so it can't be allowed to extend over it.
+ if ((fl & FLAG_LAYOUT_NO_LIMITS) != 0 && attrs.type != TYPE_SYSTEM_ERROR) {
在API 19之后,你必须找到另一种方式。也许是另一种窗口类型,或者以更严格的方式处理视图边界。