一熬北、事件滑動(dòng)
二旺嬉、攔截機(jī)制
1.外部攔截
2.內(nèi)部攔截
三荆忍、案例
1.ViewPage 嵌套 ListView滑動(dòng)沖突
1啃擦、外部攔截解決 ——重寫viewpage 的onInterceptTouchEvent
// 外部攔截法:父容器處理沖突
// 我想要把事件分發(fā)給誰(shuí)就分發(fā)給誰(shuí)
private int mLastX, mLastY;
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
// if (event.getAction() == MotionEvent.ACTION_DOWN){
// super.onInterceptTouchEvent(event);
// return false;
// }
// return true;
int x = (int) event.getX();
int y = (int) event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
mLastX = (int) event.getX();
mLastY = (int) event.getY();
break;
}
case MotionEvent.ACTION_MOVE: {
int deltaX = x - mLastX;
int deltaY = y - mLastY;
if (Math.abs(deltaX) > Math.abs(deltaY)) {
return true;
}
break;
}
case MotionEvent.ACTION_UP: {
break;
}
default:
break;
}
return super.onInterceptTouchEvent(event);
}
2囊蓝、內(nèi)部攔截解決
1.重寫viewpage 的onInterceptTouchEvent
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN){
super.onInterceptTouchEvent(event);
return false;
}
return true;
}
2.重寫Listview的dispatchTouchEvent
內(nèi)部攔截法:子view處理事件沖突
private int mLastX, mLastY;
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
getParent().requestDisallowInterceptTouchEvent(true);
break;
}
case MotionEvent.ACTION_MOVE: {
int deltaX = x - mLastX;
int deltaY = y - mLastY;
if (Math.abs(deltaX) > Math.abs(deltaY)) {
getParent().requestDisallowInterceptTouchEvent(false);
}
break;
}
case MotionEvent.ACTION_UP: {
break;
}
default:
break;
}
mLastX = x;
mLastY = y;
return super.dispatchTouchEvent(event);
}
2.SwipeRefreshLayout嵌套 ViewPager滑動(dòng)沖突
1、外部攔截解決 ——重寫SwipeRefreshLayout 的onInterceptTouchEvent
//外部攔截
private int mLastX, mLastY;
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
//外部攔截 y>x 說(shuō)明豎直滑動(dòng)令蛉,進(jìn)行攔截 否則不攔截
int x = (int) event.getX();
int y = (int) event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
mLastX = (int) event.getX();
mLastY = (int) event.getY();
break;
}
case MotionEvent.ACTION_MOVE: {
int deltaX = x - mLastX;
int deltaY = y - mLastY;
if (Math.abs(deltaY) > Math.abs(deltaX)) {
return true;
}
break;
}
case MotionEvent.ACTION_UP: {
break;
}
default:
break;
}
return super.onInterceptTouchEvent(event);
}
2聚霜、內(nèi)部攔截解決 ——重寫SwipeRefreshLayout 的onInterceptTouchEvent
1.重寫SwipeRefreshLayout 的onInterceptTouchEvent
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN){
super.onInterceptTouchEvent(event);
return false;
}
return true;
}
2.重寫ViewPager的dispatchTouchEvent
//內(nèi)部攔截
private float startX;
private float startY;
private float x;
private float y;
private float deltaX;
private float deltaY;
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
startX = ev.getX();
startY = ev.getY();
ViewCompat.setNestedScrollingEnabled(this,true);
getParent().requestDisallowInterceptTouchEvent(true);
break;
case MotionEvent.ACTION_MOVE:
x = ev.getX();
y = ev.getY();
deltaX = Math.abs(x - startX);
deltaY = Math.abs(y - startY);
if (deltaX < deltaY) {
getParent().requestDisallowInterceptTouchEvent(false);
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
break;
}
return super.dispatchTouchEvent(ev);
}
因?yàn)镾wipeRefreshLayout重寫了requestDisallowInterceptTouchEvent方法:
public void requestDisallowInterceptTouchEvent(boolean b) {
if ((VERSION.SDK_INT >= 21 || !(this.mTarget instanceof AbsListView)) && (this.mTarget == null || ViewCompat.isNestedScrollingEnabled(this.mTarget))) {
super.requestDisallowInterceptTouchEvent(b);
}
}
所以 ViewCompat.isNestedScrollingEnabled(this.mTarget)) 返回為true時(shí)才能有效;所以調(diào)用前添加
ViewCompat.setNestedScrollingEnabled(this,true);