[关闭]
@wangwangheng 2014-11-14T16:25:03.000000Z 字数 1992 阅读 1819

自定义View笔记

自定义View


一、自定义ViewGroup的注意点

  1. 自定义ViewGroup必须重写onLayout(boolean changed, int l, int t, int r, int b)以及onMeasure(int widthMeasureSpec, int heightMeasureSpec)方法,否则ViewGroup中添加的组件不会显示出来
  2. 默认情况下,ViewGroup的onDraw()方法不会被调用,如果需要调用onDraw()方法,则需要调用this.setWillNoDraw(false)这个方法
  3. onLayout()方法负责把子View放在什么位置,我们应该在onLayout()方法中遍历每一个子View并用view.layout()指定其位置,每一个View又会调用onLayout()
  4. 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以及ScrollBy

  1. scrollTo(x,y)相当于把View的内容(x,y)坐标移动到(0,0)
    scrollBy(x,y)相当于相对当前坐标进行偏移(x,y)
  2. 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);
        }
    
  3. 更多scrollTo、scrollBy请参考

    1. 图解Android View的scrollTo(),scrollBy(),getScrollX(), getScrollY()
    2. Android中滑屏初探 ---- scrollTo 以及 scrollBy方法使用说明


三、Scroller

  1. 为什么要有Scroller?

    scrollTo,scrollBy虽然能实现视图的偏移,但是没有能够很好地控制移动过程,移动是瞬间进行的,Scroller就是为了这个而设计的

  2. Scroller的作用是将View从一个起始位置通过给定的偏移量和时间执行一段动画移动到目标位置。

  3. 点击查看 - 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();
}
}

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注