View[3] scrollTo、scrollBy

 

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

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

android-2.3.3_r1源码为例

 



所以

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()方法


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()调用。





 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值