1 滑动的三种方式
- scrollTo和scrollBy
- Animation
- LayoutParams
1.1 scrollTo和scrollBy
1.view视图本身是无法滑动的,滑动的是view中的内容
2.scrollTo,scrollBy方法基于的坐标原点是view的左上角(不是屏幕左上角)
- scrollTo
scrollTo(-100,-100)
1 scrollTo(x,y); -> x,y并不是代表坐标,而是表示偏移量
2 从(0,0)移动到(100,100),偏移量为(-100,-100),即view的内容分别向右向下各移动100
3 如果偏移量没有改变,那么重复调用view的内容也不会移动
- scrollBy
scrollBy(-100,-100)
1 scrollBy(x,y)实际上就是调用了 scrollTo(mScrollX + x, mScrollY + y);
2 mScrollX、mScrollY指view内容的原始偏移量,x,y指当前偏移量(可以理解为相对于当前位置进行偏移)
2 滑动冲突
2.1滑动冲突的类型
- 子父方向不同
- 子父方向相同
- 前两种的嵌套
2.2滑动冲突的解决方案
- 外部拦截法(父View做拦截判断)
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
boolean intercept = false;
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
intercept = false;
break;
case MotionEvent.ACTION_MOVE:
if (需要拦截事件) {
intercept = true;
} else {
intercept = false;
}
break;
case MotionEvent.ACTION_UP:
intercept = false;
break;
default:
break;
}
return intercept;
}
外部拦截法需要重写onIntercerptTouchEvent(),其中对于事件序列中的ACTION_DOWN事件不能拦截(因为一旦开始拦截,后续的事件将不再会传递给子孩子了,直接由自己来处理)
- 内部拦截法(子View请求父布局做拦截判断)
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
boolean intercept = false;
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
getParent().requestDisallowInterceptTouchEvent(true);//请求父view不拦截事件
break;
case MotionEvent.ACTION_MOVE:
if (父类需要此类点击事件) {
getParent().requestDisallowInterceptTouchEvent(false);
}
break;
case MotionEvent.ACTION_UP:
break;
default:
break;
}
return super.dispatchTouchEvent(ev);
}
同时,父View需要重写onIntercerptTouchEvent
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
return false;
} else {
return true;
}
}
内部拦截法需要重写dispatchTouchEvent()和父View的onInterceptTouchEvent(),其中父view不能拦截ACTION_DOWN事件,因为ACTION_DOWN事件不受requestDisallowInterceptTouchEvent()影响,一旦父布局拦截,子view将无法通过requestDisallowInterceptTouchEvent()来控制事件传递。
网友评论