1.沖突的常見場景
- 外部滑動與內(nèi)部滑動方向不一致
- 外部滑動和內(nèi)部滑動方向一致
- (1)和(2)場景的嵌套出現(xiàn)
例如我們在Viewpage里面嵌套使用了ListView,這樣Viewpage是可以左右滑動的,但是listview同時還可以上下滑動,這樣就會出現(xiàn)第一情況這種的滑動沖突.但是我們可能在使用并沒有出現(xiàn)什么問題,這是因為Viewpage在內(nèi)部已經(jīng)解決了這個問題,所以我們可以正常的使用.要是我們在開發(fā)中也遇到類似問題怎么解決呢?其實解決的這個問題的方法是比較固定的,說難不難,說簡單也簡單.
2.解決沖突的辦法
解決思路是這樣的:在分發(fā)事件的過程中根據(jù)事件的特征就確定出事件到底應(yīng)該交給誰來處理,這樣就不會有沖突了.根據(jù)控制事件的分發(fā)的途徑,可以有一下兩個方法:
1.外部攔截法
public boolean onInterceptTouchEvent(MotionEvent e) {
boolean intercepted = false;
int x = (int) e.getX();
int y = (int) e.getY();
switch (e.getAction()) {
case MotionEvent.ACTION_DOWN:
intercepted = false;
break;
case MotionEvent.ACTION_MOVE:
if (需要攔截該事件的邏輯) {
intercepter = true;
} else {
intercepted = false;
}
break;
case MotionEvent.ACTION_UP:
intercepted = false;
break;
default:
break;
}
mLastXIntercept = x;
mLastYIntercept = y;
return intercepted;
}
這段代碼是相對固定的,只需要修改攔截的邏輯就好了.有幾點需要說明一下: ACTION_DWON這個事件必須返回false,不然的話事件將無法繼續(xù)分發(fā)給子View處理了;ACTION_UP事件也要返回false,不然子View的onClick事件就無法執(zhí)行了;但是ACTION_MOVE就可以由我們自由控制決定是否要進(jìn)行攔截了.
2.內(nèi)部攔截的方法
這種方法是將所有的事件都交給內(nèi)部View去決定這個事件是自己處理還是交還給外部View處理.
public boolean dispatchTouchEvent(MotionEvent e) {
int x = (int) e.getX();
int y = (int) e.getY();
swtich(e.getAction()) {
case MotionEvent.ACTION_DOWN:
parent.requestDisallowInterceptTouchEvent(true);
break;
case MotionEvent.ACTION_MOVE:
int detalX = x - mLastX;
int deltaY = y - mLastY;
if (父容器需要攔截事件) {
parent.requestDisallowInterceptTouchEvent(false);
}
break;
case MotionEvent.ACTION_UP:
break;
default:
break;
}
mLastX = x;
mLastY = y;
return super.dispatchTouchEvent(e);
}
public void requestDisallowInterceptTouchEvent (boolean disallowIntercept) Called when a child does not want this parent and its ancestors to intercept touch events with onInterceptTouchEvent(MotionEvent). This parent should pass this call onto its parents. This parent must obey this request for the duration of the touch (that is, only clear the flag after this parent has received an up or a cancel. Parameters – disallowIntercept True if the child does not want the parent to intercept touch events.
還要重寫外部View的onInterceptTouchEvent:
public boolean onInterceptTouchEvent(MotionEvent e) {
int action = e.getAction();
if (MotionEvent.ACTION_DOWN == action) {
return false;
} eles {
return true;
}
}
這里,我們把所有的事件都去交給內(nèi)部View去分發(fā)處理.
大體解決辦法就這兩種,這里(1)(2)(3)解決辦法其實根本是一樣的,只是(2)(3)僅僅通過手勢是無法解決的,必須根據(jù)我們自己程序的邏輯來確定這個問題.
附錄
以后每個知識點的實踐學(xué)習(xí)代碼會上傳到我的GitHub,歡迎大家一起學(xué)習(xí)-.-~