1. 程式人生 > >實現一個隨著手指滑動的View

實現一個隨著手指滑動的View

1、android View 主要6種滑動方法,分別是 

  • layout()
  • offsetLeftAndRight()和offsetTopAndBottom()
  • LayoutParams
  • scrollBy()和 scrollTo()
  • Scroller
  • 動畫

2、實現效果圖


3、自定義中使用layout()方法實習view的滑動

public class MoveView extends View {
    private int lastX, lastY;

    public MoveView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }
    public MoveView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public MoveView(Context context) {
        super(context);
    }

    
    public boolean onTouchEvent(MotionEvent event) {
        int x = (int) event.getX();
        int y = (int) event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                lastX = x;
                lastY = y;
                break;
            case MotionEvent.ACTION_MOVE:
                int offsetX = x - lastX;//計算滑動的距離
                int offsetY = y - lastY;
                //重新放置新的位置
                layout(getLeft() + offsetX, getTop() + offsetY, getRight() + offsetX, getBottom() + offsetY);
        }
        return true;
    }

}
2、offsetLeftAndRight()和offsetTopAndBottom()
  public boolean onTouchEvent(MotionEvent event) {
        int x = (int) event.getX();
        int y = (int) event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                lastX = x;
                lastY = y;
                break;
            case MotionEvent.ACTION_MOVE:
                int offsetX = x - lastX;//計算滑動的距離
                int offsetY = y - lastY;
                //重新放置新的位置
//                layout(getLeft() + offsetX, getTop() + offsetY, getRight() + offsetX, getBottom() + offsetY);
                offsetLeftAndRight(offsetX);
                offsetTopAndBottom(offsetY);
        }
        return true;
    }
3、LayoutParams 改變佈局引數的方法:
  public boolean onTouchEvent(MotionEvent event) {
        int x = (int) event.getX();
        int y = (int) event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                lastX = x;
                lastY = y;
                break;
            case MotionEvent.ACTION_MOVE:
                int offsetX = x - lastX;//計算滑動的距離
                int offsetY = y - lastY;
                //重新放置新的位置
//                layout(getLeft() + offsetX, getTop() + offsetY, getRight() + offsetX, getBottom() + offsetY);
//                offsetLeftAndRight(offsetX);
//                offsetTopAndBottom(offsetY);
                LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) getLayoutParams();
                layoutParams.leftMargin = getLeft()+offsetX;
                layoutParams.topMargin = getTop() +offsetY;
                setLayoutParams(layoutParams);
        }
        return true;
    }
4、當然使用動畫 ,scrollBy()和 scrollTo()也可以使view滑動,不足的是使用scrollBy()和 scrollTo()滑動時,是瞬間完成的,使用者體驗不太好。

5、Scroller和 View的computeScroll() 結合使用,實現view平滑的移動
public class MoveView extends View {
    private Scroller mScroller;

    public MoveView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        mScroller = new Scroller(context);
    }

    public MoveView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public MoveView(Context context) {
        super(context);
    }

    //重寫computeScroll方法
    @Override
    public void computeScroll() { //view在onDraw的時候會呼叫此方法
        super.computeScroll();
        if (mScroller.computeScrollOffset()) {
            ((View) getParent()).scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
            invalidate();
        }
    }

    //在外部呼叫這個方法即可
    public void smoothScrollTo(int destX, int destY) {
        int scrollX = getScrollX();
        int delta = destX - scrollX;
        mScroller.startScroll(scrollX, 0, delta,0 ,6000);
        invalidate();
    }

}