標籤:
1 涉及到滑動,就涉及到VIEW,大家都知道,Android的UI介面都是由一個一個的View以及View的衍生類別組成,View作為基類,而常用的布局裡面的各種布局就是它派生出來的ViewGroup的子類,ViewGroup作為各個組件的容器搭建了整體的UI。以下是android UI的結構示: 2 3 4 查看源碼 5 [java] view plain copy 6 在CODE上查看代碼片派生到My Code片 7 8 /** 9 * Implement this to do your drawing. 10 * 11 * @param canvas the canvas on which the background will be drawn 12 */ 13 protected void onDraw(Canvas canvas) { 14 } 15 16 可以發現,View的實現一般是通過繪製onDraw方法進行,如果你要改變它的介面可以重寫onDraw,達到你的效果,在源碼中,你找不到 17 18 [java] view plain copy 19 在CODE上查看代碼片派生到My Code片 20 21 public void addView(View child) { 22 addView(child, -1); 23 } 24 25 這個方法,因為它不知道,只有在它的衍生類別例如ViewGroup中會有這個方式去添加子布局。 26 27 而ViewGroup作為一個組件容器,它可以包含任何組件,可是你必須重寫他的onLayout() 方法和 onMeasure()來設定容器布局的位置和繪製它的大小才能正常顯示。 28 29 首先 ,我們必須明白在Android View視圖是沒有邊界的,Canvas是沒有邊界的,只不過我們通過繪製特定的View時對 Canvas對象進行了一定的操作,例如 : translate(平移)、clipRect(剪下)等,以便達到我們的對該Canvas對象繪製的要求 ,我們可以將這種無邊界的視圖稱為“視圖座標”-----它不受物理螢幕限制。通常我們所理解的一個Layout布局檔案只是該視圖的顯示地區,超過了這個顯示地區將不能顯示到父視圖的地區中 ,對應的,我們可以將這種有邊界的視圖稱為“布局座標”------ 父視圖給子視圖分配的布局(layout)大小。而且, 一個視圖的在螢幕的起始座標位於視圖座標起始處,如所示。 30 31 32 其實是相對於父類別檢視的左上方座標為原點(0,0),而不是整體ViewGroup的左上方為原點。 33 34 由於布局座標只能顯示特定的一塊內容,所以我們只有移動布局座標的座標原點就可以將視圖座標的任何位置顯示出來。 35 36 (註:例如cocos2D的布局就和android的布局座標原點座標不一樣,是左下角會原點,所以會有所差異。) 37 38 39 這裡就大致提下View和ViewGroup,(網上很多大神都對這塊進行了分析,這裡只是做了少量摘抄記錄)目的是為了引出今天的主角scrollTo 和 scrollBy。 40 41 42 查看下源碼可以發現: 43 44 [java] view plain copy 45 在CODE上查看代碼片派生到My Code片 46 47 <span style="font-family:SimSun;font-size:14px;"> /** 48 * The offset, in pixels, by which the content of this view is scrolled 49 * horizontally. 50 * {@hide} 51 */ 52 @ViewDebug.ExportedProperty(category = "scrolling") 53 protected int mScrollX; 54 /** 55 * The offset, in pixels, by which the content of this view is scrolled 56 * vertically. 57 * {@hide} 58 */ 59 @ViewDebug.ExportedProperty(category = "scrolling") 60 protected int mScrollY; 61 /** 62 * Return the scrolled left position of this view. This is the left edge of 63 * the displayed part of your view. You do not need to draw any pixels 64 * farther left, since those are outside of the frame of your view on 65 * screen. 66 * 67 * @return The left edge of the displayed part of your view, in pixels. 68 */ 69 public final int getScrollX() { 70 return mScrollX; 71 } 72 73 /** 74 * Return the scrolled top position of this view. This is the top edge of 75 * the displayed part of your view. You do not need to draw any pixels above 76 * it, since those are outside of the frame of your view on screen. 77 * 78 * @return The top edge of the displayed part of your view, in pixels. 79 */ 80 public final int getScrollY() { 81 return mScrollY; 82 }</span> 83 84 85 mScrollX:表示離視圖起始位置的x水平方向的位移量 86 87 mScrollY:表示離視圖起始位置的y垂直方向的位移量 88 89 分別通過getScrollX() 和getScrollY()方法獲得。 90 91 注意:mScrollX和mScrollY指的並不是座標,而是位移量。 92 93 94 [java] view plain copy 95 在CODE上查看代碼片派生到My Code片 96 97 <span style="font-family:SimSun;font-size:14px;"> /** 98 * Set the scrolled position of your view. This will cause a call to 99 * {@link #onScrollChanged(int, int, int, int)} and the view will be 100 * invalidated. 101 * @param x the x position to scroll to 102 * @param y the y position to scroll to 103 */ 104 public void scrollTo(int x, int y) { 105 if (mScrollX != x || mScrollY != y) { 106 int oldX = mScrollX; 107 int oldY = mScrollY; 108 mScrollX = x; 109 mScrollY = y; 110 invalidateParentCaches(); 111 onScrollChanged(mScrollX, mScrollY, oldX, oldY); 112 if (!awakenScrollBars()) { 113 postInvalidateOnAnimation(); 114 } 115 } 116 } 117 118 /** 119 * Move the scrolled position of your view. This will cause a call to 120 * {@link #onScrollChanged(int, int, int, int)} and the view will be 121 * invalidated. 122 * @param x the amount of pixels to scroll by horizontally 123 * @param y the amount of pixels to scroll by vertically 124 */ 125 public void scrollBy(int x, int y) { 126 scrollTo(mScrollX + x, mScrollY + y); 127 }</span> 128 129 130 從以上的代碼可以看出,scrollTo 和 scrollBy區別,其實2者的效果是一樣的。131 132 133 scrollTo(int x,int y):134 135 如果位移位置發生了改變,就會給mScrollX和mScrollY賦新值,改變當前位置。136 137 注意:x,y代表的不是座標點,而是位移量。138 139 例如:140 141 我要移動view到座標點(100,100),那麼我的位移量就是(0,,0) - (100,100) = (-100 ,-100) ,我就要執行view.scrollTo(-100,-100),達到這個效果。142 143 144 scrollBy(int x,int y):145 146 從源碼中看出,它實際上是調用了scrollTo(mScrollX + x, mScrollY + y);147 148 mScrollX + x和mScrollY + y,即表示在原先位移的基礎上在發生位移,通俗的說就是相對我們當前位置位移。149 150 根據父類VIEW裡面移動,如果移動到了超出的地方,就不會顯示。151 查看上文中的你就會知道大概。152 153 154 下面通過一個小例子瞭解下這2個方法之間的的使用,155 156 如下:
android 布局之滑動探究 scrollTo 和 scrollBy 方法使用說明