@wangwangheng
2014-11-14T16:25:03.000000Z
字数 1992
阅读 2000
自定义View
onLayout(boolean changed, int l, int t, int r, int b)
以及onMeasure(int widthMeasureSpec, int heightMeasureSpec)
方法,否则ViewGroup中添加的组件不会显示出来onDraw()
方法不会被调用,如果需要调用onDraw()
方法,则需要调用this.setWillNoDraw(false)
这个方法onLayout()
方法负责把子View放在什么位置,我们应该在onLayout()
方法中遍历每一个子View并用view.layout()
指定其位置,每一个View又会调用onLayout()
onMeasure()
方法用来确定ViewGroup本身以及制定子View的大小,一般都执行以下操作: // 指定本身大小
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(width, height);
// 指定子View的大小
int count = getChildCount();
for(int i = 0;i < count;i++){
View child = getChildAt(i);
child.measure(100, 100);
}
scrollTo(x,y)
相当于把View的内容的(x,y)
坐标移动到(0,0)
点 scrollBy(x,y)
相当于相对当前坐标进行偏移(x,y)
scrollTo(x,y)
的实现:
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(); } } }
scrollBy(x,y)
的实现:
public void scrollBy(int x, int y) { scrollTo(mScrollX + x, mScrollY + y); }
更多scrollTo、scrollBy请参考
为什么要有Scroller?
scrollTo
,scrollBy
虽然能实现视图的偏移,但是没有能够很好地控制移动过程,移动是瞬间进行的,Scroller就是为了这个而设计的
Scroller
的作用是将View从一个起始位置通过给定的偏移量和时间执行一段动画移动到目标位置。
点击查看 - Scroller源代码
注意,代码应该从startScroll
4.为了易于控制屏幕滑动,Android框架提供了'computeScroll()'方法去控制整个流程,在绘制VI我的时候,会在draw()
过程中调用该方法。为了实现偏移控制,一般定定义的View/ViewGroup都需要重载该方法,该方法默认情况下,是一个空方法:
/**
* Called by a parent to request that a child update its values for mScrollX
* and mScrollY if necessary. This will typically be done if the child is
* animating a scroll using a {@link android.widget.Scroller Scroller}
* object.
*/
public void computeScroll(){}
一个简单的实现的例子:
public void computeScroll(){
// 如果返回true,表示动画还没有结束
// 因为前面startScroll,所以只有在startScroll完成时 才会为false
if (mScroller.computeScrollOffset()) {
// 产生了动画效果,根据当前值 每次滚动一点
scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
//此时同样也需要刷新View ,否则效果可能有误差
postInvalidate();
}
}