自定义view(一)View坐标系与触摸事件

来源:互联网 发布:宝利通软件 编辑:程序博客网 时间:2024/06/01 09:11

View的坐标定位

1.安卓系统的坐标系是这样的,以左上角为原点,向右为x正,向下为Y正

2.view的坐标系是相对于父控件而言的。

所以首先明确:屏幕界面中存在两个坐标系,1.屏幕坐标系。2.view自身坐标系(以其父View为坐标参考系)于是引申出以下概念:

屏幕坐标系               getTop();       //获取子View左上角距父View顶部的距离                        getLeft();      //获取子View左上角距父View左侧的距离                        getBottom();    //获取子View右下角距父View顶部的距离                        getRight();     //获取子View右下角距父View左侧的距离                        getRawX()       //触摸时,触摸点相对于屏幕坐标系顶边和左边的距离                        getRawY()       //触摸时,触摸点相对于屏幕坐标系顶边和左边的距离view自身坐标系           getX()          //触摸时,触摸点相对于View自身坐标系顶边和左边的距离                        getY()          //触摸时,触摸点相对于View自身坐标系顶边和左边的距离

看图理解:

这里写图片描述

代码实例,实现一个可以自由拖动的view:

我们写了一个自定义view,想要拖动它,实现这个有3种方式,先看第一种因为发生了触摸事件,拖动的过程触发了:按下,移动。因为拖动不包含抬起,所以暂时不考虑抬起的事件。
于是,很自然想到要在OnTouchEvent里处理,代码如下:

 @Override    public boolean onTouchEvent(MotionEvent event) {        int x = (int) event.getX();        int y = (int) event.getY();        switch (event.getAction()){            case MotionEvent.ACTION_DOWN:                lastX = x;                laseY = y;                break;            case MotionEvent.ACTION_MOVE:                int offsetX = x-lastX;                int offsetY = y-laseY;                layout(getLeft()+offsetX,getTop()+offsetY,getRight()+offsetX,getBottom()+offsetY);                         break;            case MotionEvent.ACTION_UP:                break;        }        return true;    }
//第二种方式:     @Override    public boolean onTouchEvent(MotionEvent event) {        int x = (int) event.getX();        int y = (int) event.getY();        switch (event.getAction()){            case MotionEvent.ACTION_DOWN:                lastX = x;                laseY = y;                break;            case MotionEvent.ACTION_MOVE:                int offsetX = x-lastX;                int offsetY = y-laseY;                offsetLeftAndRight(offsetX);                offsetTopAndBottom(offsetY);                     break;            case MotionEvent.ACTION_UP:                break;        }        return true;    }
//第三种方式:     @Override    public boolean onTouchEvent(MotionEvent event) {        int x = (int) event.getX();//触摸点相对屏幕左上角的坐标距离        int y = (int) event.getY();//触摸点相对屏幕左上角的坐标距离        switch (event.getAction()){            case MotionEvent.ACTION_DOWN:                lastX = x;                laseY = y;                break;            case MotionEvent.ACTION_MOVE:                int offsetX = x-lastX;                int offsetY = y-laseY;                layoutView(offsetX,offsetY);                   break;            case MotionEvent.ACTION_UP:                break;        }        return true;    }     private void layoutView( int offsetX, int offsetY) {        RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) getLayoutParams();        params.leftMargin = getLeft()+offsetX;        params.topMargin = getTop()+offsetY;        setLayoutParams(params);    }

完整代码如下:

/** * Created by HY on 2017/5/31. */public class TView extends View {    Paint paint;    private Bitmap bitmap;    private int lastX;    private int laseY;    private Scroller scroller;    public TView(Context context) {        this(context,null);    }    public TView(Context context, AttributeSet attrs) {        this(context, attrs,0);    }    public TView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init(context);    }    private void init(Context context) {        paint = new Paint();        bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);        scroller = new Scroller(context);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        int x = (int) event.getX();        int y = (int) event.getY();        switch (event.getAction()){            case MotionEvent.ACTION_DOWN:                lastX = x;                laseY = y;                break;            case MotionEvent.ACTION_MOVE:                int offsetX = x-lastX;                int offsetY = y-laseY;//              layout(getLeft()+offsetX,getTop()+offsetY,getRight()+offsetX,getBottom()+offsetY);//                offsetLeftAndRight(offsetX);//                offsetTopAndBottom(offsetY);                layoutView(offsetX,offsetY);                break;            case MotionEvent.ACTION_UP:                break;        }        return true;    }    private void layoutView( int offsetX, int offsetY) {        RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) getLayoutParams();        params.leftMargin = getLeft()+offsetX;        params.topMargin = getTop()+offsetY;        setLayoutParams(params);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);    }    @Override    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {        super.onLayout(changed, left, top, right, bottom);    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        canvas.drawBitmap(bitmap,0,0,paint);    }}

最后效果:

这里写图片描述