View滑动学习笔记

来源:互联网 发布:社会工程学数据库 编辑:程序博客网 时间:2024/06/16 19:08

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;      }  } }
原创粉丝点击