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

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

android-2.3.3_r1源码为例

 View[3] scrollTo、scrollBy

View[3] scrollTo、scrollBy


所以

1.        他并没有改变View的位置属性,left\top\right\bottom值不变!

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

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

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

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

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

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

View[3] scrollTo、scrollBy

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)时日志输出如下

View[3] scrollTo、scrollBy


View[3] scrollTo、scrollBy 

 

 

更新

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

View[3] scrollTo、scrollBy


View[3] scrollTo、scrollBy


 

相关文章:

  • 2021-06-01
  • 2021-12-21
  • 2021-10-24
  • 2021-09-06
  • 2021-05-20
  • 2022-12-23
  • 2021-12-28
  • 2021-11-17
猜你喜欢
  • 2021-09-16
  • 2022-02-11
  • 2022-12-23
  • 2021-04-29
  • 2022-12-23
  • 2022-12-23
  • 2021-08-10
相关资源
相似解决方案