26
2017
09

View滑动学习笔记

1).实现滑动的方式:

  • 通过动画给View增加平移滑动的效果
  • 通过改变View的LayoutParams使得View重新布局
  • 通过View自身提供的ScrollTo/scrollBy方法实现滑动
  • 通过layout

1.通过动画
这里以属性动画为例:

ObjectAnimator.ofFloat(targetView,"translationX",0,100).setDuration(1000).start();

2.通过改变View的LayoutParams
示例:

RelativeLayout.LayoutParams layoutParams    (RelativeLayout.LayoutParams) targetView.getLayoutParams();
                layoutParams.leftMargin +=100;
                targetView.setLayoutParams(layoutParams);

3.通过ScrollTo/scrollBy

/** mScrollX和mScrollY表示:View的内容(content)相对于View本身在水平或垂直方向的偏移量. **/
public final int getScrollX() {
    return mScrollX;
}
public final int getScrollY() {
    return mScrollY;
}

/** * Set the scrolled position of your view. This will * cause a call to {@link #onScrollChanged(int, int, * int,int)}and the view will be invalidated. * @param x the x position to scroll to * @param y the y position to scroll to */
public void scrollTo(int x, int y) {
    if (mScrollX != x || mScrollY != y) {
        int oldX = mScrollX;
        int oldY = mScrollY;
        mScrollX = x;
        mScrollY = y;
        invalidateParentCaches();
        onScrollChanged(mScrollX, mScrollY, oldX, oldY);
        if (!awakenScrollBars()) {
        postInvalidateOnAnimation();
        }
    }
}

public void scrollBy(int x, int y) {
        scrollTo(mScrollX + x, mScrollY + y);
    }
}
  • 用法
 targetView.scrollTo(100,0),targetView的内容向左滑动到(-1000)。 
 targetView.scrollTo(-100,0),targetView的内容向右滑动到(1000)。
 targetView.scrollBy(100,0),targetView的内容相对于上个位置向左滑动100像素。
 targetView.scrollBy(-100,0),targetView的内容相对于上个位置向右滑动100像素。
  • 滑动的是ViewGroup/View的内容,不是ViewGroup/View本身。
  • 滑动是一瞬间的。
  • scrollBy()底层是由scrollTo()实现的
  • scrollTo()时为何参数值和坐标反向?
    由scrollTo(int x, int y)的注释可知调用该方法会回调onScrollChanged()方法,并且会重新绘制view,draw()过程中最终会调用invalidate()方法。
public void invalidate(int l, int t, int r, int b) {
    final int scrollX = mScrollX;
    final int scrollY = mScrollY;
    //scrollTo时为何参数和坐标反向的真实原因
    invalidateInternal(l - scrollX, t - scrollY, r - scrollX, b - scrollY, true, false);

特别注意:如果你给一个ViewGroup调用scrollTo()方法滚动的是ViewGroup里面的内容,如果想滚动一个ViewGroup则再给他嵌套一个外层,滚动外层即可。

2).弹性滑动实现方式:
1. Scroller
这里写图片描述
使用示例:

   Scroller mScroller= new Scroller(mContext);

/** * 缓慢滚动到指定位置 * @param destX 指定滚动到的X轴位置 * @param destY 指定滚动到的Y轴位置 */
    private void smoothScrollTo(int destX, int destY) {
        //获取当前滚动的距离
        int scrollX = getScrollX();
        //获取需要滚动的偏移量
        int delta = destX - scrollX;
        //设置1000ms内滚动到delta位置,而效果就是慢慢滑动
        mScroller.startScroll(scrollX, 0, delta, 0, 1000);
        invalidate();
    }

    /** * 持续滚动,实现慢慢滑动 */
    @Override
    public void computeScroll() {
        if (mScroller.computeScrollOffset()){
            scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
            postInvalidate();
        }
    }

2.
ObjectAnimator.ofFloat(targetView,"translationX",0,100).setDuration(100).start();

3.值动画+layoutParams或值动画+scrollTo/scrollBy

ValueAnimator animator = ValueAnimator.ofFloat(0, 100 );  
        animator.setTarget(targetView);  
        animator.setDuration(1000).start();  
        animator.addUpdateListener(new AnimatorUpdateListener()  
        {  
            @Override  
            public void onAnimationUpdate(ValueAnimator animation)  
            {  
            float value=(Float) animation.getAnimatedValue();
                targetView.ScrollTo(value,0);  
            }  

4.handler +scrollTo/scrollBy

上一篇:我们是怎样在项目内落地自动化测试体系的 下一篇:解决APP冷启动白屏/黑屏的问题