在最近的項目中用到了LinearLayout中嵌套一個ImageView的佈局,但是點擊事件設置在LinearLayout中卻無響應,綜合網上的教程總結一下幾種可能導致的情況:
1.如果在ImageView中和LinearLayout同時設置點擊事件,會發現觸發的是ImageView的點擊事件,說明點擊事件被子控件ImageView消耗了。這涉及到事件分發的機制,簡述下解決方案:
在XML佈局文件中的LinearLayout項設置android:clickable="true",ImageView設置android:clickable="false"。
採用這種方案的話最好將LinearLayout下所有子控件的都設置爲不可點擊。屬於比較麻煩的方法。
2.既然提到了事件分發,就說一個酷炫一點的解決方法:
通過繼承LinearLayout,重寫onInterceptTouchEvent方法實現攔截,該方法從父view傳向子view,意思爲是否中斷事件的傳遞。返回值用false表示不攔截事件,接着就在重寫的onInterceptTouchEvent中進行操作。此時只要點擊LinearLayout,都會先優先調用這個方法,也就是在事件被傳遞到子控件前調用,從而實現攔截。
3.搜索資料得知還有第三種常見解決方案:
當點擊事件發生時子控件會獲得焦點,此時可以通過descendantFocusability屬性來控制viewGroup與子控件之間的關係。該屬性的值有三種:
beforeDescendants:viewgroup會優先其子類控件而獲取到焦點
afterDescendants:viewgroup只有當其子類控件不需要獲取焦點時才獲取焦點
blocksDescendants:viewgroup會覆蓋子類控件而直接獲得焦點
因此在上述項目中只需要在LinearLayout中設置android:descendantFocusability= "blocksDescendants"即可以屏蔽子控件獲得焦點。
特別注意:以上方法對於重寫了onInterceptTouchEvent與onTouchEvent的控件會不起作用。