如果我有一个显示在用户壁纸上方的活动,有什么方法可以阻止壁纸接收我已经处理的触摸事件?从 onTouchEvent 返回 true 或 false 似乎没有区别。
问问题
662 次
1 回答
1
我想通了!
private View empty;
@Override public void onCreate(Bundle savedState)
{
super.onCreate(savedState);
empty = new View(this);
setContentView(empty);
}
@Override public void onAttachedToWindow()
{
View topview = getLayoutInflater().inflate(R.layout.mylayout, null);
PopupWindow pw = new PopupWindow(topview);
pw.setWindowLayoutMode(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
pw.showAtLocation(empty, 0, 0, 0);
}
关键见解来自研究WindowManagerService.java的源代码;具体来说,这部分:
if (srcWin != null
&& pointer.getAction() == MotionEvent.ACTION_DOWN
&& mWallpaperTarget == srcWin
&& srcWin.mAttrs.type != WindowManager.LayoutParams.TYPE_KEYGUARD) {
sendPointerToWallpaperLocked(relWin, pointer, eventTime);
}
动态壁纸必须满足以下四个条件才能接收触摸事件:
srcWin
(注定要接收触摸的窗口)必须是非空的。我不知道这个检查什么时候会失败,但我认为可以安全地假设这不是一个解决方案。- 事件必须是
ACTION_DOWN
为了执行这些检查。如果初始向下已被转发到壁纸,其他代码会将触摸事件转发到壁纸,而无需进行所有这些检查。也不是解决办法。 mWallpaperTarget
, 壁纸正在下方显示的窗口, 必须等于srcWin
, 触摸的目标窗口。- 窗户不能是键卫。由于 Android 不再允许非系统应用程序使用
TYPE_KEYGUARD
,这不是一个解决方案。
那么诀窍就是在顶部简单地分层另一个窗口!因此,我们现在有一个按以下顺序排列的窗口:
- 壁纸 窗口
mWallpaperTarget
具有@android:style/Theme.Holo.Wallpaper.NoTitleBar
或类似的活动窗口。srcWin
, 这PopupWindow
由于 Android 只检查严格相等,并且mWallpaperTarget
!= srcWin
,触摸不会转发到壁纸,并且不允许交互。
于 2013-04-12T19:08:58.447 回答