首先 ,我們必須明白在Android View視圖是沒有邊界的,Canvas是沒有邊界的,只不過我們通過繪制特定的View時(shí)對
???Canvas對象進(jìn)行了一定的操作,例如 : translate(平移)、clipRect(剪切)等,以便達(dá)到我們的對該Canvas對象繪制的要求 ,
???我們可以將這種無邊界的視圖稱為“視圖坐標(biāo)”-----它不受物理屏幕限制。通常我們所理解的一個(gè)Layout布局文件只是該視
???圖的顯示區(qū)域,超過了這個(gè)顯示區(qū)域?qū)⒉荒茱@示到父視圖的區(qū)域中 ,對應(yīng)的,我們可以將這種無邊界的視圖稱為“布局坐標(biāo)”
????------ 父視圖給子視圖分配的布局(layout)大小。 而且, 一個(gè)視圖的在屏幕的其實(shí)坐標(biāo)位于視圖坐標(biāo)起始處,如下圖所示。
?
???????? 這么來說吧 ,世界本是無邊無界的,可是我們的眼睛我們的心約束了我們所看到的“世界” 。
?
??? ?? 如下所示:
?????????????
??????????????
????????????? 黑色框框表示該子視圖的布局坐標(biāo), 褐色框框表示該子視圖的視圖坐標(biāo)--該坐標(biāo)是無限的,超過了父視圖給子視圖
?????? 規(guī)定的區(qū)域后,不再顯示該超出內(nèi)容。
?
??? ?? ? ?那么下面的問題就是:如何將我們的視圖的任意坐標(biāo)能顯示到該視圖的中心坐標(biāo)上呢? 由于該布局位置是只能顯示特定的
? 一塊視圖內(nèi)容 ,因此我們需要通過scrollTo()或者scrollBy()方法將我們期望的視圖“滾動”至布局坐標(biāo)上。
?
????? 在View.java中提供了了如下兩個(gè)變量以及相應(yīng)的屬性方法去讀取滾動值 ,如下: View.java類中???
| 02 | ?????* The offset, in pixels, by which the content of this view is scrolled |
| 06 | ????protected?int?mScrollX;???//該視圖內(nèi)容相當(dāng)于視圖起始坐標(biāo)的偏移量?? , X軸 方向 |
| 08 | ?????* The offset, in pixels, by which the content of this view is scrolled |
| 12 | ????protected?int?mScrollY;???//該視圖內(nèi)容相當(dāng)于視圖起始坐標(biāo)的偏移量?? , Y軸方向 |
| 15 | ?????* Return the scrolled left position of this view. This is the left edge of |
| 16 | ?????* the displayed part of your view. You do not need to draw any pixels |
| 17 | ?????* farther left, since those are outside of the frame of your view on |
| 20 | ?????* @return The left edge of the displayed part of your view, in pixels. |
| 22 | ????public?final?int?getScrollX() { |
| 23 | ????????return?mScrollX; |
| 27 | ?????* Return the scrolled top position of this view. This is the top edge of |
| 28 | ?????* the displayed part of your view. You do not need to draw any pixels above |
| 29 | ?????* it, since those are outside of the frame of your view on screen. |
| 31 | ?????* @return The top edge of the displayed part of your view, in pixels. |
| 33 | ????public?final?int?getScrollY() { |
| 34 | ????????return?mScrollY; |
?
??????注意,所謂的“by which the content of this view is scrolled”表示該偏移量只針對于該View中onDraw()方法里的
??具體內(nèi)容實(shí)現(xiàn),而不針對背景圖片等 。具體原因可參考<Android中View繪制流程以及invalidate()等相關(guān)方法分析>
?
?????提示:下文中提到的當(dāng)前視圖內(nèi)容是在繪制在布局坐標(biāo)處的內(nèi)容。
?
?????public void?scrollTo(int x, int y)
????????????? 說明:在當(dāng)前視圖內(nèi)容偏移至(x , y)坐標(biāo)處,即顯示(可視)區(qū)域位于(x , y)坐標(biāo)處。
??????? 方法原型為: View.java類中
查看源碼 打印?
| 02 | ?* Set the scrolled position of your view. This will cause a call to |
| 03 | ?* {@link #onScrollChanged(int, int, int, int)} and the view will be |
| 05 | ?* @param x the x position to scroll to |
| 06 | ?* @param y the y position to scroll to |
| 08 | public?void?scrollTo(int?x,?int?y) { |
| 10 | ????if?(mScrollX != x || mScrollY != y) { |
| 11 | ????????int?oldX = mScrollX; |
| 12 | ????????int?oldY = mScrollY; |
| 13 | ????????mScrollX = x;??//賦新值,保存當(dāng)前便宜量 |
| 15 | ????????//回調(diào)onScrollChanged方法 |
| 16 | ????????onScrollChanged(mScrollX, mScrollY, oldX, oldY); |
| 17 | ????????if?(!awakenScrollBars()) { |
| 18 | ????????????invalidate();??//一般都引起重繪 |
?
?????public voidscrollBy(int x, int y)? ??
??????????? 說明:在當(dāng)前視圖內(nèi)容繼續(xù)偏移(x , y)個(gè)單位,顯示(可視)區(qū)域也跟著偏移(x,y)個(gè)單位。
??????? 方法原型為: View.java類中
| 02 | ???* Move the scrolled position of your view. This will cause a call to |
| 03 | ???* {@link #onScrollChanged(int, int, int, int)} and the view will be |
| 05 | ???* @param x the amount of pixels to scroll by horizontally |
| 06 | ???* @param y the amount of pixels to scroll by vertically |
| 08 | ??// 看出原因了吧 。。 mScrollX 與 mScrollY 代表我們當(dāng)前偏移的位置 , 在當(dāng)前位置繼續(xù)偏移(x ,y)個(gè)單位 |
| 09 | ??public?void?scrollBy(int?x,?int?y) { |
| 10 | ??????scrollTo(mScrollX + x, mScrollY + y); |
????????
?????????????
?????? 第一個(gè)小Demo非常簡單 ,大家重點(diǎn)理解與掌握scrollTo() 與 scrollBy()函數(shù)的用法和區(qū)別。
?
????? ?第二個(gè)小Demo則有了Launcher的模樣,能夠左右切換屏幕 。實(shí)現(xiàn)功能如下: 采用了一個(gè)自定義ViewGroup,該ViewGroup
?? 對象包含了3個(gè)LinearLayout子視圖,并且以一定的布局坐標(biāo)(由layout()方法指定)顯示在ViewGroup上。 接下來,即可調(diào)用該
???ViewGroup對象的scrollTo或者scrollBy()方法切換指定視圖內(nèi)容了,即切換屏幕。 呵呵 ,挺好玩的吧 。
?
?????? 如果對View繪制流程不懂的,可以參考我的這篇博客<Android中View繪制流程以及invalidate()等相關(guān)方法分析> 。
與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖
總結(jié)
以上是生活随笔為你收集整理的Android滑屏 mScrollX mScrollY scrollTo() scrollBy()的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。