如果我有一个显示在用户壁纸上方的活动,有没有办法阻止壁纸接收我已经处理过的触摸事件?从onTouchEvent返回true或false似乎没有任何区别。
答案 0 :(得分: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
(预定接收触摸的窗口)必须为非null。我不知道这次检查何时会失败,但我认为可以安全地假设这不是一个解决方案。ACTION_DOWN
。如果初始向下已经转发到壁纸,则其他代码将触摸事件转发到壁纸而不用打扰所有这些检查。也不是解决方案。mWallpaperTarget
,壁纸显示在下方的窗口必须等于srcWin
,即触摸所需的窗口。TYPE_KEYGUARD
,因此这不是解决方案。然后诀窍是简单地将另一个窗口叠加在上面!因此,我们现在按顺序拥有一堆窗口:
mWallpaperTarget
,其中包含@android:style/Theme.Holo.Wallpaper.NoTitleBar
或类似的内容。srcWin
,PopupWindow
由于Android仅检查严格的相等性,mWallpaperTarget
!= srcWin
,因此触摸不会转发到壁纸,也不允许进行互动。