http://blog.csdn.net/vipzjyno1/article/details/24577023#comments

http://blog.csdn.net/vipzjyno1/article/details/24577023#comments

http://blog.csdn.net/vipzjyno1/article/details/24577023#comments

http://blog.csdn.net/vipzjyno1/article/details/24577023#comments

http://blog.csdn.net/vipzjyno1/article/details/24577023#comments

android 布局之滑动探究 scrollTo 和 scrollBy 方法使用说明 分类:android 2141人阅读 评论(3) 收藏 举报 Android 移动 scrollTo scrollBy View

涉及到滑动,就涉及到VIEW,大家都知道,android的UI界面都是由一个一个的View以及View的派生类组成,View作为基类,而常用的布局里面的各种布局就是它派生出来的ViewGroup的子类,ViewGroup作为各个组件的容器搭建了整体的UI。以下是android UI的结构示示意图:

android 布局之滑动探究 scrollTo 和 scrollBy 方法使用说明_第1张图片

查看源码

[java] view plain copy
  1. /**
  2. *Implementthistodoyourdrawing.
  3. *
  4. *@paramcanvasthecanvasonwhichthebackgroundwillbedrawn
  5. */
  6. protectedvoidonDraw(Canvascanvas){
  7. }
可以发现, View的实现一般是通过绘制 onDraw方法 进行,如果你要改变它的界面可以重写 onDraw,达到你的效果,在源码中,你找不到

[java] view plain copy
  1. publicvoidaddView(Viewchild){
  2. addView(child,-1);
  3. }
这个方法,因为它不知道,只有在它的派生类例如 ViewGroup中会有这个方式去添加子布局。

而ViewGroup作为一个组件容器,它可以包含任何组件,可是你必须重写他的onLayout() 方法和onMeasure()来设置容器布局的位置和绘制它的大小才能正常显示。

首先 ,我们必须明白在Android View视图是没有边界的,Canvas是没有边界的,只不过我们通过绘制特定的View时对 Canvas对象进行了一定的操作,例如 : translate(平移)、clipRect(剪切)等,以便达到我们的对该Canvas对象绘制的要求 ,我们可以将这种无边界的视图称为“视图坐标”-----它不受物理屏幕限制。通常我们所理解的一个Layout布局文件只是该视图的显示区域,超过了这个显示区域将不能显示到父视图的区域中 ,对应的,我们可以将这种有边界的视图称为“布局坐标”------ 父视图给子视图分配的布局(layout)大小。而且, 一个视图的在屏幕的起始坐标位于视图坐标起始处,如下图所示。

android 布局之滑动探究 scrollTo 和 scrollBy 方法使用说明_第2张图片

其实是相对于父类视图的左上角坐标为原点(0,0),而不是整体ViewGroup的左上角为原点。

由于布局坐标只能显示特定的一块内容,所以我们只有移动布局坐标的坐标原点就可以将视图坐标的任何位置显示出来。

(注:例如cocos2D的布局就和android的布局坐标原点坐标不一样,是左下角会原点,所以会有所差异。)


这里就大致提下View和ViewGroup,(网上很多大神都对这块进行了分析,这里只是做了少量摘抄记录)目的是为了引出今天的主角scrollTo 和 scrollBy。


查看下源码可以发现:

[java] view plain copy
  1. <spanstyle="font-family:SimSun;font-size:14px;">/**
  2. *Theoffset,inpixels,bywhichthecontentofthisviewisscrolled
  3. *horizontally.
  4. *{@hide}
  5. */
  6. @ViewDebug.ExportedProperty(category="scrolling")
  7. protectedintmScrollX;
  8. /**
  9. *Theoffset,inpixels,bywhichthecontentofthisviewisscrolled
  10. *vertically.
  11. *{@hide}
  12. */
  13. @ViewDebug.ExportedProperty(category="scrolling")
  14. protectedintmScrollY;
  15. /**
  16. *Returnthescrolledleftpositionofthisview.Thisistheleftedgeof
  17. *thedisplayedpartofyourview.Youdonotneedtodrawanypixels
  18. *fartherleft,sincethoseareoutsideoftheframeofyourviewon
  19. *screen.
  20. *
  21. *@returnTheleftedgeofthedisplayedpartofyourview,inpixels.
  22. */
  23. publicfinalintgetScrollX(){
  24. returnmScrollX;
  25. }
  26. /**
  27. *Returnthescrolledtoppositionofthisview.Thisisthetopedgeof
  28. *thedisplayedpartofyourview.Youdonotneedtodrawanypixelsabove
  29. *it,sincethoseareoutsideoftheframeofyourviewonscreen.
  30. *
  31. *@returnThetopedgeofthedisplayedpartofyourview,inpixels.
  32. */
  33. publicfinalintgetScrollY(){
  34. returnmScrollY;
  35. }</span>

mScrollX:表示离视图起始位置的x水平方向的偏移量

mScrollY:表示离视图起始位置的y垂直方向的偏移量

分别通过getScrollX() 和getScrollY()方法获得。

注意:mScrollX和mScrollY指的并不是坐标,而是偏移量。


[java] view plain copy
  1. <spanstyle="font-family:SimSun;font-size:14px;">/**
  2. *Setthescrolledpositionofyourview.Thiswillcauseacallto
  3. *{@link#onScrollChanged(int,int,int,int)}andtheviewwillbe
  4. *invalidated.
  5. *@paramxthexpositiontoscrollto
  6. *@paramytheypositiontoscrollto
  7. */
  8. publicvoidscrollTo(intx,inty){
  9. if(mScrollX!=x||mScrollY!=y){
  10. intoldX=mScrollX;
  11. intoldY=mScrollY;
  12. mScrollX=x;
  13. mScrollY=y;
  14. invalidateParentCaches();
  15. onScrollChanged(mScrollX,mScrollY,oldX,oldY);
  16. if(!awakenScrollBars()){
  17. postInvalidateOnAnimation();
  18. }
  19. }
  20. }
  21. /**
  22. *Movethescrolledpositionofyourview.Thiswillcauseacallto
  23. *{@link#onScrollChanged(int,int,int,int)}andtheviewwillbe
  24. *invalidated.
  25. *@paramxtheamountofpixelstoscrollbyhorizontally
  26. *@paramytheamountofpixelstoscrollbyvertically
  27. */
  28. publicvoidscrollBy(intx,inty){
  29. scrollTo(mScrollX+x,mScrollY+y);
  30. }</span>

从以上的代码可以看出, scrollTo 和 scrollBy区别,其实2者的效果是一样的。


scrollTo(int x,int y):

如果偏移位置发生了改变,就会给mScrollX和mScrollY赋新值,改变当前位置。

注意:x,y代表的不是坐标点,而是偏移量。

例如:

我要移动view到坐标点(100,100),那么我的偏移量就是(0,,0) - (100,100) = (-100 ,-100) ,我就要执行view.scrollTo(-100,-100),达到这个效果。


scrollBy(int x,int y):

从源码中看出,它实际上是调用了scrollTo(mScrollX + x, mScrollY + y);

mScrollX + x和mScrollY + y,即表示在原先偏移的基础上在发生偏移,通俗的说就是相对我们当前位置偏移。

根据父类VIEW里面移动,如果移动到了超出的地方,就不会显示。

查看上文中的示意图你就会知道大概。


下面通过一个小例子了解下这2个方法之间的的使用,

效果图如下:

android 布局之滑动探究 scrollTo 和 scrollBy 方法使用说明_第3张图片

核心代码就是本文讲的2个方法,这里就列出代码了。

提供一个简单的DEMO:下载地址

这里大致搞清楚了这2个方法后,对后面的Scroller拖动类以及实现几个拖动效果就更加有帮助了。

25

更多相关文章

  1. Android五大布局详解及属性
  2. Android 控件布局实现卡片效果,阴影效果
  3. Android 键盘布局总结
  4. Android 5.0 SystemUI 视图框架
  5. Android 开发 之 折叠布局(CollapsingToolbarLayout)
  6. Android开发中布局属性的使用汇总
  7. FrameLayout的使用——android开发之xml布局文件

随机推荐

  1. Beginning Android 4--Exercises 1
  2. Android之打开闪光灯关键代码
  3. 自定义progressbar使用图片
  4. Android 获取剩余存储空间
  5. Android中全屏无标题设置(Android学习随笔
  6. Android性能测试(内存、cpu、fps、流量、G
  7. Shape实现圆形图片
  8. Android 启动界面Splash
  9. android 左右翻页
  10. Activity-GridView