【发布时间】:2017-09-12 13:01:15
【问题描述】:
我正在尝试在锁屏上显示一个视图,并且还希望能够部分显示它(例如,当视图处于“非活动状态”时,一半的视图在屏幕外)。 使用WindowManager.LayoutParams.TYPE_SYSTEM_ERROR 描述的here 和here 类型(以及其他一些建议使用此标志的帖子),我可以在锁屏上显示它。但与标志 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值),api 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)
262696flags = 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 类型。
【问题讨论】:
-
那个 gif 让我想起了这个库 github.com/recruit-lifestyle/FloatingView
标签: android layoutparams android-windowmanager