首先得注意:
scrollTo()和scrollBy()
这个两个方法如果在view中使用,移动的将是view的内容,而不是view本身,如果在viewGroup中使用,移动的是所有的子view。
getScrollX()、getScrollY()
getScrollX()、getScrollY()得到的是偏移量,是相对于自己初始位置(没有滑动前的位置)的滑动偏移距离,当scroll事件触发时,这两个方法有值,否则,值为0。getScrollX()返回对应的是mScrollX,代表水平方向的偏移量,getScrollY()返回对应的是mScrollY,代表垂直方向的偏移量。而mScrollX,
mScrollY的正负值则有如下的解释:
mScrollX为正代表着当前内容相对于初始位置向左偏移了mScrollX的距离,mScrollX为负表示当前内容相对于初始位置向右偏移了mScrollX的距离。
为什么呢?这与坐标系有关。屏幕左边为X坐标轴的正方向,屏幕上边为Y坐标轴的正方向,与传统的坐标轴方向刚好相反。
说明:图中黄色矩形区域表示的是一个可滑动的View控件,绿色虚线矩形为滑动控件中的滑动内容。注意这里的坐标是相反的。(例子来源于: http://blog.csdn.net/bigconvience/article/details/26697645 )
(1)调用scrollTo(100,0)表示将View中的内容移动到距离内容初始显示位置的x=100,y=0的地方,效果如下图:
(2)调用scrollTo(0,100)效果如下图:
(3)调用scrollTo(100,100)效果如下图:
(4)
调用scrollTo(
-100
,0)效果如下图:
通过上面几个图,可以清楚看到scrollTo的作用和滑动坐标系的关系!!!!!!!!!!!!!
在继续向下之前,还得延伸一些东西:
View提供获取坐标的方法 :getTop getLeft getRight getBottom
MotionEvent提供获取坐标的方法 :getX getY getRawX getRawY
(
注明:以下内容来源:
http://www.jianshu.com/p/4c7aa2eff9c6)
![](https://i-blog.csdnimg.cn/blog_migrate/9771844d2b5062e0692dd6cef0237960.webp?x-image-process=image/format,png)
上述地址总结了这么一句话:
不管采用哪一种方式,实现的思路其实都是大致相同的。就是当触摸 View 的时候,系统记下当前触摸点的坐标;当手指一动的时候,系统记下移动后的触摸点坐标,两次的相差就是这次移动的偏移量,然后通过偏移量来修改 View 的坐标。这样不断重复,就实现了滑动的过程。
![](https://i-blog.csdnimg.cn/blog_migrate/e2ef16cb548b5127ea20cae24de7e186.webp?x-image-process=image/format,png)
@Override public boolean onTouchEvent(MotionEvent event) {
//检测到触摸事件后 第一时间得到相对于父控件的触摸点坐标 并赋值给x,y
int x = (int) event.getX();
int y = (int) event.getY();
switch (event.getAction()) {
//触摸事件中绕不开的第一步,必然执行,将按下时的触摸点坐标赋值给 lastX 和 last Y
case MotionEvent.ACTION_DOWN:
lastX = x;
lastY = y;
break;
//触摸事件的第二步,这时候的x,y已经随着滑动操作产生了变化,用变化后的坐标减去首次触摸时的坐标得到 相对的偏移量
case MotionEvent.ACTION_MOVE:
int offsetX = x - lastX;
int offsetY = y - lastY;
//使用 layout 进行重新定位
layout(getLeft() + offsetX, getTop() + offsetY, getRight() + offsetX, getBottom() + offsetY);
break;
}
return true;
}
这里layout方法变换为
scrollTo(x,y)方法;
Over !Over !Over !Over !