Android移动View的几种方式

概述

View位置的变化和触控操作都涉及到MotionEvent类,MotionEvent中封装了一些与触摸相关的东西,比如触摸事件Action,触摸坐标等。移动View无疑就是改变其位置,通常有以下几种方式。

onTouchEvent

View 类中,我们知道有一个layout方法是给View定位的 ,结合onTouchEvent方法 ,我们可以很好的实现一个View的移动.

int lastX, lastY;    @Override
    public boolean onTouchEvent(MotionEvent event) {        int rawX = (int) event.getRawX();        int rawY = (int) event.getRawY();        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:

                lastX = rawX;
                lastY = rawY;                break;            case MotionEvent.ACTION_MOVE:                int offsetX = rawX - lastX;                int offsetY = rawY - lastY;

                 layout(getLeft()+offsetX,
                 getTop()+offsetY,
                 getRight()+offsetX,
                 getBottom()+offsetY);

                lastX = rawX;
                lastY = rawY;                break;
        }        return true;
    }12345678910111213141516171819202122232425262728293031323334

这里面使用了绝对坐标,使用绝对坐标的时候,需要在每次ACTION_MOVE后重新设置初始坐标.

offsetLeftAndRight()

使用offsetLeftAndRight();offsetTopAndBottom();方法,通过设置偏移量来滑动View

    int lastX, lastY;    @Override
    public boolean onTouchEvent(MotionEvent event) {        int rawX = (int) event.getRawX();        int rawY = (int) event.getRawY();        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:

                lastX = rawX;
                lastY = rawY;                break;            case MotionEvent.ACTION_MOVE:                int offsetX = rawX - lastX;                int offsetY = rawY - lastY;                //layout(getLeft()+offsetX,
                // getTop()+offsetY,
                // getRight()+offsetX,
                // getBottom()+offsetY);

                offsetLeftAndRight(offsetX);
                offsetTopAndBottom(offsetY);
                lastX = rawX;
                lastY = rawY;                break;
        }        return true;
    }12345678910111213141516171819202122232425262728293031323334353637

LayoutParams

LayoutParams,使用LayoutParams滑动View,通过改变布局参数来达到滑动View的目的.

 int lastX, lastY;    @Override
    public boolean onTouchEvent(MotionEvent event) {        int rawX = (int) event.getRawX();        int rawY = (int) event.getRawY();        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:

                lastX = rawX;
                lastY = rawY;                break;            case MotionEvent.ACTION_MOVE:                int offsetX = rawX - lastX;                int offsetY = rawY - lastY;                // layout(getLeft()+offsetX,
                // getTop()+offsetY,
                // getRight()+offsetX,
                // getBottom()+offsetY);//                offsetLeftAndRight(offsetX);//                offsetTopAndBottom(offsetY);

                ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) getLayoutParams();
                layoutParams.leftMargin = getLeft() + offsetX ;
                layoutParams.topMargin = getTop() +offsetY;
                setLayoutParams(layoutParams);

                lastX = rawX;
                lastY = rawY;                break;
        }        return true;
    }123456789101112131415161718192021222324252627282930313233343536373839404142

ScrollTo() ScrollBy()

使用ScrollTo() 和ScrollBy() 方法来改变View 的位置.

    int lastX, lastY;    @Override
    public boolean onTouchEvent(MotionEvent event) {        int rawX = (int) event.getRawX();        int rawY = (int) event.getRawY();        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:

                lastX = rawX;
                lastY = rawY;                break;            case MotionEvent.ACTION_MOVE:                int offsetX = rawX - lastX;                int offsetY = rawY - lastY;                // layout(getLeft()+offsetX,
                // getTop()+offsetY,
                // getRight()+offsetX,
                // getBottom()+offsetY);//                offsetLeftAndRight(offsetX);//                offsetTopAndBottom(offsetY);//                ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) getLayoutParams();//                layoutParams.leftMargin = getLeft() + offsetX ;//                layoutParams.topMargin = getTop() +offsetY;//                setLayoutParams(layoutParams);

                ((View) getParent()).scrollBy( -offsetX, -offsetY);

                lastX = rawX;
                lastY = rawY;                break;
        }        return true;
    }123456789101112131415161718192021222324252627282930313233343536373839404142434445

这里需要注意的是 
1.首先我们的ScrollTo() and ScrollBy()方法移动的是View的Content 
2.我们移动的是画布,因此需要设置相反的值,才能让View 跟随手指移动.

Scroller

使用Scroller类来移动View,与ScrollBy()方法关系紧密,ScrollBy()移动是瞬时完成,Scroller类在ACTION_MOVE中对偏移量进行划分,达到平滑效果.我们需要三个步骤

 mScroller = new Scroller(context);1
@Override
    public void computeScroll() {        super.computeScroll();        if (mScroller.computeScrollOffset()) {
            ((View) getParent()).scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
            invalidate();
        }
    }12345678
 case MotionEvent.ACTION_UP:

                ViewGroup viewGroup = (ViewGroup) getParent();         mScroller.startScroll(viewGroup.getScrollX(),viewGroup.getScrollY(),-viewGroup.getScrollX(),-viewGroup.getScrollY());

                invalidate();                break;1234567

Property Animation

通过 属性动画对View位置对改变

        int w = text.getWidth();        int screenW = UiUtil.getScreenWidth();        int transX = screenW - w;
        ObjectAnimator transAnim = ObjectAnimator.ofFloat(text, "translationX", 0, transX);1234

ViewDragHelper

使用v4包中的ViewDragHelper能很好的实现View的滑动和事件分发,典型谷歌官方的 Drawerlayout

实例:ViewDragHelper实现QQ侧滑效果DragLayout[github]

你可能感兴趣的:(Android移动View的几种方式)