View的滑动
View的滑动实现基本有三种思路,一种是通过ScrollTo和ScrollBy,一种是通过动画给View添加平移效果,第三种是改变View的LayoutParams属性来使得View重新布局。
scrollTo/scrollBy
使用这类两个方法,我们要知道mScrollX和mScrollY这两个变量,他们指的View的内容与View之间的偏移量。在滑动过程中mScrollX的值等于View左上缘和View内容左上缘的距离,mScrollY同理。View的边缘指View的位置,由四个顶点决定。scrollTo和scrollBy只能改变View的内容。获取这两个值由getScrollX()和getScrollY()得到。
他们的单位为像素。当View的边缘在View的内容的右边时,mScrollX为正,即从右往左滑,反过来为负。上下滑动也是同理,从下往上滑为正。
比如上面这张图,mScrollX为正100。
scrollTo(int x,int y)表示移动到视图的那个坐标点。哪个视图调用这个方法,那么这个视图的(x,y)点就与父容器的左上角对齐
scrollBy(int dx, int dy) 表示在视图的X、Y方向上各移动dx、dy距离
dx>0表示视图(View或ViewGroup)的内容从右向左滑动;反之,从左向右滑动
dy>0表示视图(View或ViewGroup)的内容从下向上滑动;反之,从上向下滑动
使用动画
使用动画是操作View的translationX和translationY属性,也就是平移。可以采用普通动画,也可以采用属性动画。若采用属性动画则需要兼容3.0以下的版本,需要采用开源动画库nineoldandroids,不过现在手机系统基本都是4.0以上。
要注意,View的平移只是对View的影像做操作,实际上View的位置不变,如果View具有点击效果,那么只有点击View原来的位置才有效,平移后的位置并没有效果。
使用LayoutParams属性。
当我们需要把View的位置向右平移100像素,那么只要设置marginLeft的值增加100px即可。或者在view的左边放置一个空View,宽度为0,改变空View的宽度,也能把View挤到右边。
MarginLayoutParams params= (MarginLayoutParams ) btn.getLayoutParams();
params.width +=100;
params.leftMargin+=100;
btn.requestLayout();
View的弹性滑动
上面的滑动都是比较生硬的,我们需要的是一种渐进性的滑动。弹性滑动实现的方式也是有多种,但他们的思想都一样,就是将一次完整的滑动分解为若干次小的滑动并在一段时间内完成。
使用Scroller
下面是Scroller的典型用法
scroller = new Scroller(context);
private void smoothScrollTo(int destX,int destY) {
int scrollY=getScrollY();
int deltaY = destY-scrollY;
scroller.startScroll(0,scrollY,0,destY,1000);
invalidate();
}
@Override
public void computeScroll() {
if(scroller.computeScrollOffset()){
scrollTo(scroller.getCurrX(),scroller.getCurrY());
postInvalidate();
}
}
我们来了解一下Scroller的工作原理,滑动的关键地方是invalidate()方法。调用startScroll()只是传递相关参数。invalidate会导致View重绘,在View的draw方法会去调用computeScroll方法,在computeScroll中进行滑动,而postInvalidate又会二次重绘,这又导致computeScroll被调用,循环下去,直到滑动结束。computeScrollOffset()方法会根据时间的流逝来计算当前的scrollX和scrollY.返回值true表示滑动还未结束,false则是结束。
以上内容大部分摘自《安卓开发艺术探索》,若想理解更仔细请阅读原书。