今天我們開發時發生了「靈異事件」

各位看倌請看一下這段 code 

view.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        GG.d("RDBG:onClick() => view.isClickable()="
         +view.isClickable()+" / id="+view.getId());
    }
});

然後觸發點擊輸出如下

 

你沒看錯,我們在 onClick 裡面印出 view 的 clickable 竟然是 false

見鬼了,這不合邏輯呀

都不行 click 了,還怎麼觸發 onClick method ?

 

講到這裡,有經驗的看倌們會說

一定是 setOnClickListener() 的順序錯了

各位可以看下方的原碼

public void setOnClickListener(@Nullable OnClickListener l) {
    if (!isClickable()) {
        setClickable(true);
    }
    getListenerInfo().mOnClickListener = l;
}

沒錯,若 setClickable(false) 是在 setOnClickListener() 前使用的話

setOnClickListener 時會自動幫您改回 true 

必竟不能 click 的話,設監聽要幹麻,是吧?

 

但這也無法解釋此問題

因為我們在 onClick 裡面印出來的的確是 false

也就是說它不是被改掉的,而是真的 false,卻可點擊

 

為了找出問題原因

我們點進原碼一探究竟

終於在 View.dispatchTouchEvent() 中找到一點蛛絲馬跡

ListenerInfo li = mListenerInfo;
if (li != null && li.mOnTouchListener != null
        && (mViewFlags & ENABLED_MASK) == ENABLED
        && li.mOnTouchListener.onTouch(this, event)) {
    result = true;
}

只有在符合 mOnTouchListener != null 而且 enabled 的情況下

才會執行 mOnTouchListener.onTouch()

所以我回頭 call setEnabled(false)

成功 !!!

不過這個方法是封鎖了全部的 touch 事件 ( ex: 長按、拖曳…等 )

之後再來研究有沒有更佳的解法。

 

 

 

 

 

 

 

 

 

 

 

 

 


arrow
arrow

    顏澤偉 發表在 痞客邦 留言(0) 人氣()