Android移動View的幾種方式

概述


View位置的變化和觸控操做都涉及到MotionEvent類,MotionEvent中封裝了一些與觸摸相關的東西,好比觸摸事件Action,觸摸座標等。移動View無疑就是改變其位置,一般有如下幾種方式。git

onTouchEvent


View 類中,咱們知道有一個layout方法是給View定位的 ,結合onTouchEvent方法 ,咱們能夠很好的實現一個View的移動.github

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後從新設置初始座標.web

offsetLeftAndRight()


使用offsetLeftAndRight();offsetTopAndBottom();方法,經過設置偏移量來滑動Viewide

    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 跟隨手指移動.spa

Scroller


使用Scroller類來移動View,與ScrollBy()方法關係緊密,ScrollBy()移動是瞬時完成,Scroller類在ACTION_MOVE中對偏移量進行劃分,達到平滑效果.咱們須要三個步驟code

 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位置對改變orm

        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]

相關文章
相關標籤/搜索