0
如果我有一个活动显示在用户的壁纸上方,有什么办法可以防止壁纸接收我已经处理的触摸事件?从onTouchEvent返回true或false似乎没有区别。拦截动态壁纸触摸事件?
如果我有一个活动显示在用户的壁纸上方,有什么办法可以防止壁纸接收我已经处理的触摸事件?从onTouchEvent返回true或false似乎没有区别。拦截动态壁纸触摸事件?
我已经想通了!
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
,这是触摸的目的地。TYPE_KEYGUARD
,因此这不是解决方案。然后,诀窍就是将另一个窗口层叠在上面!因此,我们现在有窗户的顺序栈:
mWallpaperTarget
,其中有@android:style/Theme.Holo.Wallpaper.NoTitleBar
或similiar。srcWin
,该PopupWindow
由于Android只检查严格的平等,mWallpaperTarget
!= srcWin
,触摸被不转发到壁纸,而不是允许的交互。