2013-03-11 92 views
0

如果我有一個活動顯示在用戶的壁紙上方,有什麼辦法可以防止壁紙接收我已經處理的觸摸事件?從onTouchEvent返回true或false似乎沒有區別。攔截動態壁紙觸摸事件?

回答

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. 該窗口不得是keyguard。由於Android不再允許非系統應用使用TYPE_KEYGUARD,因此這不是解決方案。

然後,訣竅就是將另一個窗口層疊在上面!因此,我們現在有窗戶的順序棧:

  • 壁紙窗口
  • 活動窗口,mWallpaperTarget,其中有@android:style/Theme.Holo.Wallpaper.NoTitleBar或similiar。
  • srcWin,該PopupWindow

由於Android只檢查嚴格的平等,mWallpaperTarget!= srcWin,觸摸被不轉發到壁紙,而不是允許的交互。