前三天收到位網友的私信求助,問題大概如標題所示。具體是下面的情況,個人感覺,這個問題挺有趣,也會在實際項目開發中很常見。不想看前奏的請直接跳至解決方法。
問題原型:
父控件是自定義的 LinearLayout,目的是實現下拉刷新,這個自定義View的實現下拉操作思想是通過檢測 onTouch 事件,然后,子控件有一個 scrollView,它是完全為了實現下滾和滾到底部實現加載更多的監聽。看到這,我相信任何一個有類似項目開發經驗的人,都會感到很熟悉的。下拉刷新+下滑加載更多。
在 scrollView 里面的第一層View里面有很多一樣的自定義的 View,每個有具備自身的 onClick 和 onTouch 事件,目的是為了在用戶點擊的時候實現變色和相應。
問題來了,根據他說的,每次點擊,總是先實現 自定義View的 onTouch 的down,然后是 onClick,而 父 Linearlayout的 onTouch是最后實現,而且,父的 action_down 沒有執行,這樣就直接導致了父View 拿不到用戶的 點擊坐標,下拉刷新出問題!就是說,各種沖突。
我們知道,在同一個 View中,注意,是同一個 View,沒嵌套的情況下,用戶手勢事件執行順序是:
onTouch->onLongClick->onClick。
交談細節:
我問:你自己百度過了嗎?
他答:嗯,百度上有onClick和onTouch的沖突例子,但是全都是針對同一個 View的情況下,而且 無論onTouch返回false不阻斷還是true阻斷繼續傳送下去,都是無作用。
他的回答很清晰,他的這個狀況的沖突是 嵌套的,大家大可百度下,因為我在幫他的時間里,也百度過,基本無答案。最能接近的是父View的onTouch里面使用 requestDisallowInterceptTouchEvent 來允許這個手勢事件能傳給 子View,但是,他的這個問題是,兒子不爽父親先的。確實蛋碎。
我再問:是不是你的布局有問題,怎么會是子 View 阻斷 父 View?
他再答:他的布局就是正常的嵌套。
在無語了一會之后,想了下,覺得這樣應該可以搞定。
解決方法:
既然傳統的解決方法解決不了,我當時想到的是:
1:子View 使用父類的 onTouch 接口來實現點擊和改變顏色,總之就是子View不要自己再實現 onClick和onTouch;
2:父View 實現個接口,供子View實現自己的onTouch內容;
3:當用戶onTouch的時候,父View 在恰當的時候調用該接口,實現子View的請求的功能。
這樣所會產生的問題:
因為它的這個父View是整個使用onTouch來實現下拉的,所以:
1:用戶點擊后會產生兩次的 onTouch執行,一次是子 View,第二次是 父View。
這樣就需要他來使用邏輯區分了,邏輯區分不難,幾個 boolean 即可,所用內存幾個 bit。
最后問他,這樣能否接受,他說試試先,剛剛發信息來,完美解決。逐有感而發此文。
在我們百度或請教人都解決不了的問題的情況下,應該自己思考下動手解決!