Android Viewを指で動かす


概要
Androidのスライドイベントは、実際にはViewの移動であり、原理はアニメーションと似ている.本質は絶えず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;
    }

ここでは絶対座標を使用する、絶対座標を使用する場合は、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;
    }

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

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

ここで注意しなければならないのは1.まず我々のScrollTo() and ScrollBy()メソッドが移動するのはViewのContent 2である.私たちが移動するのはキャンバスなので、Viewが指に従って移動するように逆の値を設定する必要があります.
Scroller
Scrollerクラスを使用してViewを移動する、ScrollBy()メソッドと密接な関係があり、ScrollBy()の移動は瞬時に完了し、ScrollerクラスはACTION_MOVEでオフセット量を区分し、平滑化効果を達成する.3つのステップが必要です
 mScroller = new Scroller(context);
@Override
    public void computeScroll() {
        super.computeScroll();
        if (mScroller.computeScrollOffset()) {
            ((View) getParent()).scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
            invalidate();
        }
    }
 case MotionEvent.ACTION_UP:

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

                invalidate();

                break;

Property Animation
Android属性アニメーション、
        int w = text.getWidth();
        int screenW = UiUtil.getScreenWidth();
        int transX = screenW - w;
        ObjectAnimator transAnim = ObjectAnimator.ofFloat(text, "translationX", 0, transX);

ViewDragHelper
v 4パッケージのViewDragHelperを使用すると、Viewのスライドとイベントの配布がうまく実現し、典型的なGoogle公式Drawerlayout
ViewDragHelper QQサイドスライド効果を実現DragLayout[github]