【问题标题】:Intercept Live Wallpaper Touch Events?拦截动态壁纸触摸事件?
【发布时间】:2013-03-11 23:12:53
【问题描述】:

如果我有一个显示在用户壁纸上方的活​​动,有什么方法可以阻止壁纸接收我已经处理过的触摸事件?从 onTouchEvent 返回 true 或 false 似乎没有区别。

【问题讨论】:

    标签: android live-wallpaper touch-event


    【解决方案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);
    }
    

    动态壁纸必须满足四个条件才能接收触摸事件:

    1. srcWin(注定要接收触摸的窗口)必须为非空。我不知道这个检查什么时候会失败,但我认为可以肯定地认为这不是一个解决方案。
    2. 事件必须是ACTION_DOWN 才能执行这些检查。如果初始向下已被转发到壁纸,其他代码会将触摸事件转发到壁纸,而无需进行所有这些检查。也不是解决方案。
    3. mWallpaperTarget,壁纸正在显示的窗口,必须等于srcWin,触摸的目标窗口。
    4. 窗口不能是键盘保护。由于 Android 不再允许非系统应用使用TYPE_KEYGUARD,因此这不是解决方案。

    那么诀窍就是在上面简单地分层另一个窗口!因此,我们现在有一个按此顺序排列的窗口:

    • 壁纸窗口
    • 活动窗口mWallpaperTarget,具有@android:style/Theme.Holo.Wallpaper.NoTitleBar 或类似名称。
    • srcWinPopupWindow

    由于 Android 只检查严格相等,并且mWallpaperTarget != srcWin,触摸不会转发到壁纸,并且不允许交互。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多