美文网首页
3.2 View的滑动

3.2 View的滑动

作者: 武安长空 | 来源:发表于2016-06-20 14:11 被阅读37次

    1. 实现滑动的三种方式

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

    2. scrollTo/scrollBy

    使用:

    view.scrollTo(200,200);
    view.scrollBy(200,200);
    

    源码:

    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);
    }
    

    scrollBy实际上是调用了scrollTo方法,他实现的是相对滑动;而scrollTo实现的是绝对滑动。
    在滑动过程中,mScrollX的值总是等于View的左边缘和View的内容的左边缘在水平方向的距离,而mScrollY的值等于View上边缘和View内容的上边缘的竖直距离。
    View的边缘指View的位置。内容边缘指View中的内容的边缘。scrollTo/scrollBy只能改变View的内容边缘,而不能改变View在布局中的位置。mScrollX和mScrollY的单位是像素,是有正负的。起始位置-终点位置的结果值就是scrollX和scrollY的值,是正就是正,是负就是负。也就是当View左边缘在View内容左边缘的右边时,mScrollX为正。反之为负。

    3. 使用动画

    objectAnimator = ObjectAnimator.ofFloat(view,"translationX",0,500).setDuration(5000);
    objectAnimator.addListener(new Animator.AnimatorListener() {
        @Override
        public void onAnimationStart(Animator animation) {
        }
    
        @Override
        public void onAnimationEnd(Animator animation) {
            Log.e("aaa", "x=" + view.getX() + ",y=" + view.getY() + ",translationX=" + view.getTranslationX() + ",translationY=" + view.getTranslationY());
        }
    
        @Override
        public void onAnimationCancel(Animator animation) {
    
        }
    
        @Override
        public void onAnimationRepeat(Animator animation) {
    
        }
    });
    view.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Log.e("aaa", "x=" + view.getX() + ",y=" + view.getY() + ",translationX=" + view.getTranslationX() + ",translationY=" + view.getTranslationY());
            objectAnimator.start();
        }
    });
    

    动画启动前打印x,translationX的值,动画结束后,也打印他们的值如下:

    x=30.0,y=30.0,translationX=0.0,translationY=0.0 
    x=530.0,y=30.0,translationX=500.0,translationY=0.0
    

    前文说过

    x=left + translationX
    

    3.0以上的属性动画其位置是随着动画移动了的,而3.0以下的机器由于不支持属性动画,所以位置不随着动画移动,这是动画的主要缺点。

    4. 改变布局参数

    RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) view.getLayoutParams();
    lp.width+=100;
    lp.leftMargin+=100;
    view.requestLayout();
    // 或者 view.setLayoutParams(lp);
    

    5. 三种方式的比较

    • scrollTo/scrollBy:操作简单,适合对View内容的滑动
    • 动画:操作简单,主要用于没有交互的View或者复杂动画。
    • 改变参数布局:操作稍微复杂,适用于有交互的Veiw

    6. 小栗子

    public class DemoButton extends Button {
        int mLastX, mLastY;
    
        public DemoButton(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            int x = (int) event.getRawX();
            int y = (int) event.getRawY();
            switch (event.getAction()) {
                case MotionEvent.ACTION_MOVE:
                    int deltaX = x - mLastX;
                    int deltaY = y - mLastY;
                    int translationX = (int) getTranslationX() + deltaX;
                    int translationY = (int) getTranslationY() + deltaY;
                    setTranslationX(translationX);
                    setTranslationY(translationY);
                    break;
            }
            mLastX = x;
            mLastY = y;
            return true;
        }
    }
    

    这个例子其实不用动画,因为move的响应非常快,已经达到了动画要求的梯度值,所以直接设置其值就可以。

    相关文章

      网友评论

          本文标题:3.2 View的滑动

          本文链接:https://www.haomeiwen.com/subject/uauwdttx.html