看了很久的View的事件沖突解決辦法,一直沒有什么好的頭緒,今天用了半天時間,好好看了一下view的事件原理,雖說沒有自己看源碼(主要是看不懂),但是在眾多大神的博客里面也是通過源碼來分析,所以也當(dāng)自己看了吧,下面自己把自己目前理解的記錄下來,希望自己能夠很好的理解這一部分知識。
首先所有的我們看得見的都是繼承自View的,我們將View的子類(不是很準(zhǔn)確)分為View和ViewGroup。事件分為dispatchTouchEvent(MotionEvent ev)、onInterceptTouchEvent(MotionEvent ev)、onTouchEvent(MotionEvent event)。而view是沒有oninterceptTouchEvent,因為事件傳遞給它,它要么處理(ontouchEvent()返回true)、要么不處理,交給父類的ontouchEvent()處理。父View如果攔截了ACTION_DOWN則子View完全接收不到事件序列,所以一般情況下我們在ACTION_DOWN是不攔截事件的,在ACTION_MOVE中,判斷我們什么情況需要攔截(返回true),ACTION_UP事件我們一般也不攔截,如果攔截了子View獲取不到up事件,里面的click事件也不會響應(yīng)(click()是由ontouchEvent()調(diào)用)而我們常見的滑動沖突有1、水平與豎直方向交叉 2、水平與水平方向的交叉 3、多層嵌套滑動。我們解決滑動沖突一般有兩種思路,1、(外部攔截)父View判斷何時該攔截(自己處理),何時不攔截交由子View處理。2、(內(nèi)部攔截)子View判斷,自己什么時候需要處理事件(調(diào)用parent.requestDisallowInterceptEvent(true)),因為父View的move 和 up事件受這個方法返回值影響。其他關(guān)于View事件處理的零散知識點:
//獲取touchSlop值 ViewConfiguration viewConfiguration = ViewConfiguration.get(context); mTouchSlop = ViewConfigurationCompat.getScaledPagingTouchSlop(viewConfiguration); 這個值表示的的手機能識別的最小的滑動距離,可以通過這個值和我們手指移動的距離來判斷我們的動作是不是滑動,一般用在ACTION_MOVE里面如果是則進(jìn)行攔截等等。//創(chuàng)建Scroller實例 mScroller = new Scroller(context); //調(diào)用startScroll()方法來初始化滾動,并刷新界面 mScroller.startScroll(getScrollX(),0,dx,0); invalidate();重繪會調(diào)用以下方法(需要自己重寫) @Override public void computeScroll() { super.computeScroll(); if(mScroller.computeScrollOffset()){ scrollTo(mScroller.getCurrX(),mScroller.getCurrY()); invalidate(); } }scrollTo和scrollBy的區(qū)別:前者是絕對滾動,相對的這個布局,后者是相對與上一次滾動后的滾動。新聞熱點
疑難解答