標簽:android 移動 scrollto scrollby view
涉及到滑動,就涉及到VIEW,大家都知道,android的UI界面都是由一個一個的View以及View的派生類組成,View作爲基類,而常用的布局裏面的各種布局就是它派生出來的ViewGroup的子類,ViewGroup作为各个组件的容器搭建了整体的UI。以下是android UI的结构示示意图:
查看源碼
/** * Implement this to do your drawing. * * @param canvas the canvas on which the background will be drawn */ protected void onDraw(Canvas canvas) { }可以發現,View的實現一般是通過繪制onDraw方法進行,如果你要改變它的界面可以重寫onDraw,达到你的效果,在源码中,你找不到
public void addView(View child) { addView(child, -1); }這個方法,因爲它不知道,只有在它的派生類例如ViewGroup中會有這個方式去添加子布局。
而ViewGroup作为一个组件容器,它可以包含任何组件,可是你必须重写他的onLayout() 方法和 onMeasure()來設置容器布局的位置和繪制它的大小才能正常顯示。
首先 ,我们必须明白在Android View视图是没有边界的,Canvas是没有边界的,只不过我们通过绘制特定的View时对 Canvas对象进行了一定的操作,例如 : translate(平移)、clipRect(剪切)等,以便达到我们的对该Canvas对象绘制的要求 ,我们可以将这种无边界的视图称为“視圖坐標”-----它不受物理屏幕限制。通常我们所理解的一个Layout布局文件只是该视图的显示区域,超过了这个显示区域将不能显示到父视图的区域中 ,对应的,我们可以将这种有边界的视图称为“布局坐標”------ 父视图给子视图分配的布局(layout)大小。而且, 一个视图的在屏幕的起始坐标位于視圖坐標起始处,如下图所示。
其實是相對于父類視圖的左上角坐標爲原點(0,0),而不是整體ViewGroup的左上角爲原點。
由于布局坐標只能显示特定的一块内容,所以我们只有移動布局坐標的坐标原点就可以将視圖坐標的任何位置显示出来。
(注:例如cocos2D的布局就和android的布局坐標原点坐标不一样,是左下角会原点,所以会有所差异。)
這裏就大致提下View和ViewGroup,(网上很多大神都对这块进行了分析,这里只是做了少量摘抄记录)目的是为了引出今天的主角scrollTo
和 scrollBy。
/**
* The offset, in pixels, by which the content of this view is scrolled
* horizontally.
* {@hide}
*/
@ViewDebug.ExportedProperty(category = "scrolling")
protected int mScrollX;
/**
* The offset, in pixels, by which the content of this view is scrolled
* vertically.
* {@hide}
*/
@ViewDebug.ExportedProperty(category = "scrolling")
protected int mScrollY;
/**
* Return the scrolled left position of this view. This is the left edge of
* the displayed part of your view. You do not need to draw any pixels
* farther left, since those are outside of the frame of your view on
* screen.
*
* @return The left edge of the displayed part of your view, in pixels.
*/
public final int getScrollX() {
return mScrollX;
}
/**
* Return the scrolled top position of this view. This is the top edge of
* the displayed part of your view. You do not need to draw any pixels above
* it, since those are outside of the frame of your view on screen.
*
* @return The top edge of the displayed part of your view, in pixels.
*/
public final int getScrollY() {
return mScrollY;
}
mScrollY:表示離視圖起始位置的y垂直方向的偏移量
分別通過getScrollX() 和getScrollY()方法獲得。
注意:mScrollX和mScrollY指的並不是坐標,而是偏移量。
/**
* Set the scrolled position of your view. This will cause a call to
* {@link #onScrollChanged(int, int, int, int)} and the view will be
* invalidated.
* @param x the x position to scroll to
* @param y the y position to scroll to
*/
public void scrollTo(int x, int y) {
if (mScrollX != x || mScrollY != y) {
int oldX = mScrollX;
int oldY = mScrollY;
mScrollX = x;
mScrollY = y;
invalidateParentCaches();
onScrollChanged(mScrollX, mScrollY, oldX, oldY);
if (!awakenScrollBars()) {
postInvalidateOnAnimation();
}
}
}
/**
* Move the scrolled position of your view. This will cause a call to
* {@link #onScrollChanged(int, int, int, int)} and the view will be
* invalidated.
* @param x the amount of pixels to scroll by horizontally
* @param y the amount of pixels to scroll by vertically
*/
public void scrollBy(int x, int y) {
scrollTo(mScrollX + x, mScrollY + y);
}
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個方法之間的的使用,
效果圖如下:
核心代碼就是本文講的2個方法,這裏就列出代碼了。
提供一個簡單的DEMO:下載地址
這裏大致搞清楚了這2個方法後,對後面的Scroller拖動類以及實現幾個拖動效果就更加有幫助了。
android 布局之滑动探究 scrollTo 和 scrollBy 方法使用说明,码迷,mamicode.com
android 布局之滑动探究 scrollTo 和 scrollBy 方法使用说明
標簽:android 移動 scrollto scrollby view
原文地址:http://blog.csdn.net/vipzjyno1/article/details/24577023