View[3] scrollTo、scrollBy
使用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()调用。
标签:
相关文章
-
无相关信息