Android 自定义View--DragView

自定义View的Demo,这是一个可以拖动的View.
这里写图片描述

代码


/**
 * Created by shixi_tianrui1 on 16-10-5.
 * 可以拖动的View
 */

public class DragView extends View {

    private static final String TAG = "DragView";

    private float mLastX = 0;
    private float mLastY = 0;

    private int mWidth;
    private int mHeight;

    private Paint mPaint;

    private static final int DEFAULT_WIDTH = 200;
    private static final int DEFAULT_HEIGHT = 200;
    private static final int DEFAULT_RECT_WIDTH = 100;
    private static final int DEFAULT_RECT_HEIGHT = 100;


    public DragView(Context context) {
        this(context, null);
    }

    public DragView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public DragView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setColor(getResources().getColor(R.color.colorPrimary));
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        // 处理wrap_content的情况
        int width = resolveSize(DEFAULT_WIDTH, widthMeasureSpec);
        int height = resolveSize(DEFAULT_HEIGHT, heightMeasureSpec);
        setMeasuredDimension(width, height);
    }




    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mLastX = event.getX();
                mLastY = event.getY();
                postInvalidate();
                return true;
            case MotionEvent.ACTION_MOVE:
                mLastX = event.getX();
                mLastY = event.getY();
                postInvalidate();
                break;
            case MotionEvent.ACTION_UP:
                mLastX = event.getX();
                mLastY = event.getY();
                break;

        }
        return super.onTouchEvent(event);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mWidth = w;
        mHeight = h;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int rectWidth = DEFAULT_RECT_WIDTH;
        int rectHeight = DEFAULT_RECT_HEIGHT;
        Log.d(TAG, "onDraw: mLastX: " + mLastX + " mLastY: " + mLastY);
        canvas.drawRect(mLastX, mLastY, rectWidth + mLastX, rectHeight + mLastY, mPaint);
    }
}

使用scroll 实现DragView

Android 针对View 提供了scrollBy(),scrollTo() 者两种滑动方法,但者两种方法均是针对View中的内容进行滑动.

下图中,灰色表示View中的内容区域,移动只是针对内容区域而言.
这里写图片描述
获取View的父布局,然后进行相对滑动,这样也就实现了滑动的效果
((View) getParent()).scrollBy(-offsetX, -offsetY);

但是使用

//  使View本身开始移动
offsetLeftAndRight(offsetX);
offsetTopAndBottom(offsetY);

可以针对当前View本身进行滑动

代码


/**
 * Created by shixi_tianrui1 on 16-10-5.
 * <p>
 * 使用ScrollBy实现DragView
 */

public class DragView2 extends View implements View.OnClickListener {
    private static final String TAG = "DragView";

    private float mLastX;
    private float mLastY;

    public DragView2(Context context) {
        this(context, null);
    }

    public DragView2(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public DragView2(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        setBackgroundColor(getResources().getColor(R.color.colorPrimary));
        Log.d(TAG, "DragView2: ");
        setOnClickListener(this);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int offsetX = (int) (event.getX() - mLastX);
        int offsetY = (int) (event.getY() - mLastY);
        switch (event.getAction()) {

            case MotionEvent.ACTION_MOVE:
                // 使用父容器向相反的方向移动,即可产生移动效果
//                ((View) getParent()).scrollBy(-offsetX, -offsetY);


                //  使View本身开始移动
                offsetLeftAndRight(offsetX);
                offsetTopAndBottom(offsetY);
                break;
            case MotionEvent.ACTION_UP:
                mLastX = event.getX();
                mLastY = event.getY();
                break;
        }
        return super.onTouchEvent(event);
    }


    @Override
    public void onClick(View v) {
        Log.d(TAG, "onClick: ");
        Toast.makeText(getContext(), "onClick", Toast.LENGTH_SHORT).show();
    }
}

ScrollTo ScrollBy 详解

成员变量

mScrollX:表示离视图起始位置的x水平方向的偏移量
mScrollY:表示离视图起始位置的y垂直方向的偏移量

分别通过getScrollX()getScrollY()方法获得。

注意:mScrollX和mScrollY指的并不是坐标,而是偏移量

scrollTo(int x,int y):

如果偏移位置发生了改变,就会给mScrollX和mScrollY赋新值,改变当前位置。
注意:x,y代表的不是坐标点,而是偏移量。

例如:
我要移动view到坐标点(100,100),那么我的偏移量就是(0,,0) - (100,100) = (-100 ,-100) ,我就要执行view.scrollTo(-100,-100),达到这个效果。

scrollBy(int x,int y):

从源码中看出,它实际上是调用了scrollTo(mScrollX + x, mScrollY + y);
mScrollX + x和mScrollY + y,即表示在原先偏移的基础上在发生偏移,通俗的说就是相对我们当前位置偏移。

根据父类VIEW里面移动,如果移动到了超出的地方,就不会显示。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值