素材巴巴 > 程序开发 >

View[3] scrollTo、scrollBy

程序开发 2023-09-09 17:31:43

 

使用scrollTo()、scrollBy()可以实现移动View中的内容的效果。

他的本质其实是给View自身设置一个偏移(scrollX, scrollY),然后触发重绘。在重绘的时候,父ViewGroup会先获取到此View的偏移,然后将此偏移取反(-scrollX, -scrollY),应用到此View的画布上,再交给此View进行绘制。

以android-2.3.3_r1源码为例

 



所以

1.        他并没有改变View的位置属性,lefttoprightbottom值不变!

2.        scrollTo()、scrollBy()参数的坐标系跟画布坐标系是相反的,比如说scrollTo(100, 100)是先将画布向左上移动 translate(-100,-100)。

3.        效果是移动画布中的内容,但画布背景是在变换之前绘制的,所以背景不会移动。

如下TextView的背景是白色,调用scrollTo()/scrollBy()以后仅文本发生了移动

4.        可以使用getScrollX()、getScrollY()获取当前内容滑动的偏移,当然这个值也是跟画布坐标系相反的

5.        如果需要监听滑动改变,可以重写onScrollChanged()函数。每次调用scrollTo()/scrollBy()的时候,都会先调用onScrollChanged()函数。

从API23开始也提供了setOnScrollChangeListener()方法


6.        这个效果是一次完成的,如果需要平滑效果需要结合Scroller/OverScroller。

 

如下TextView

public class MyTextView extends TextView {

    public MyTextView(Context context) {
       super(context);
    }

    public MyTextView(Context context, AttributeSet attrs) {
       super(context, attrs);
    }

    public MyTextView(Context context, AttributeSet attrs, int defStyleAttr) {
       super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
       Log.e("shadowfaxghh", "onMeasure()");
       super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
       Log.e("shadowfaxghh", "onLayout()");
       super.onLayout(changed, left, top, right, bottom);
    }

    @Override
    protected void onDraw(Canvas canvas) {
       Log.e("shadowfaxghh", "onDraw()");

       Matrix matrix =canvas.getMatrix();
       printMatrix(matrix);

       super.onDraw(canvas);
    }

    public void printMatrix(Matrix matrix){
       float[] values=new float[9];
       matrix.getValues(values);

       for(int i=0; i<3; i++){
           StringBuffer buffer=new StringBuffer();
           for(int j=0; j<3; j++){
               buffer.append(values[i*3+j]+"  ");
           }
           Log.e("shadowfaxghh", buffer.toString());
       }
    }

    @Override
    protected void onScrollChanged(int horiz, int vert, int oldHoriz, int oldVert) {
       super.onScrollChanged(horiz, vert, oldHoriz, oldVert);

       Log.e("shadowfaxghh", "scrollX="+horiz+" scrollY="+vert);
    }
}

 

当调用scrollTo(100,0)时日志输出如下


 

 

 

更新

在后面写Scroller的时候,在高版本上某些情况下,在computeScroll()中,调用scrollTo()以后并没有调用invalidate(),暂时不明白原因,只好自己加上invalidate()调用。





 


标签:

素材巴巴 Copyright © 2013-2021 http://www.sucaibaba.com/. Some Rights Reserved. 备案号:备案中。