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

private static final int MESSAGE_SCROLL_TO = 1;
 private static final int FRAME_COUNT = 30;
 private static final int DELATED_TIME = 33;

 private int mCount = 0;

  @suppressLint("HandlerLeak")
  private Handler handler = new handler(){
  public void handleMessage(Message msg){
      switch(msg.what){
      case MESSAGE_SCROLL_TO:
              mCount ++ ;
              if (mCount <= FRAME_COUNT){
                  float fraction = mCount / (float) FRAME_COUNT;
                  int scrollX = (int) (fraction * 100);
                  mButton1.scrollTo(scrollX,0);
                  mHandelr.sendEmptyMessageDelayed(MESSAGE_SCROLL_TO , DELAYED_TIME);
              }
              break;
      default : break;
      }
  }
 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值