通过layout()方法实现控件的移动以及MotionEvent.getX()和MotionEvent.getRowX()的区别

来源:互联网 发布:优化标签怎么设置 编辑:程序博客网 时间:2024/05/16 10:17
 自定义控件中,使自定义控件根据手势滑动而移动的实现方式有很多,这篇文章讲解通过layout()方法,实现移动。   我们知道,android 系统在控件绘制的过程中,会通过onLayout()方法来设置显示的位置,那么,我们是否可以调用相关方法,通过改变view的布局位置,实现view随手势移动呢,答案是肯定的,通过layout()方法,即可实现。调用layout()方法,会使View对自己重新布局。  下面来看代码实现:  在我们的自定义view中,重写onTouchEvent 方法,其获取坐标,可以用event.getRawX()或者event.getX(),先看具体实现,在讲解不同之处:

1.使用getRowX()实现

  @Override    public boolean onTouchEvent(MotionEvent event) {        switch(event.getAction()) {            case MotionEvent.ACTION_DOWN:                mLastX = (int) event.getRawX();                mLastY = (int) event.getRawY();                Log.e("DragView","ACTION_DOWN:" + "rowX:" + mLastX +";getX:"+event.getX());                break;            case MotionEvent.ACTION_MOVE:                int moveX = (int) event.getRawX();                int moveY = (int) event.getRawY();                int offsetX = moveX - mLastX;                int offsetY = moveY -mLastY;                layout(getLeft() + offsetX,getTop() + offsetY,                        getRight() + offsetX ,getBottom() + offsetY);                mLastX = moveX;                mLastY = moveY;                Log.e("DragView","ACTION_MOVE:" + "rowX:" + event.getRawX() +";getX:"+event.getX());                break;            case MotionEvent.ACTION_UP:                break;        }        return true;    }

2.使用getX()实现

 @Override    public boolean onTouchEvent(MotionEvent event) {        switch(event.getAction()) {            case MotionEvent.ACTION_DOWN:                mDownX = (int) event.getX();                mDownY = (int) event.getY();                break;            case MotionEvent.ACTION_MOVE:                int moveX = (int) event.getX();                int moveY = (int) event.getY();                int offsetX = moveX - mDownX;                int offsetY = moveY - mDownY;                layout(getLeft() + offsetX,getTop() + offsetY,                        getRight() + offsetX ,getBottom() + offsetY);                break;            case MotionEvent.ACTION_UP:                break;        }        return true;    }
大家看出有什么区别了吗?显而易见,当用getRowX()时,需要用一个变量,记录上一次的位置,而当getX()时,则不需要。这是为什么呢。原因就是所使用的坐标系不同。在Android系统中,存在两种坐标系,一种是Android坐标系,一种是视图坐标系。android 坐标系,是将屏幕最左上角的坐顶点作为Android坐标系的原点从这个点向右,是X轴的正方向,从该点向下是Y轴的正方向,系统提供了getLocationOnScreen()来获取android坐标系中点的位置,同时,在触摸事件中getRowX()和getRowY()方法所获得的坐标,同样也是Android坐标系中的坐标。Android坐标系如图所示:![Android坐标系](http://img.blog.csdn.net/20161126152933582)另一种坐标系是视图坐标系,它描述了子视图在父视图中的位置关系,在该坐标系下,原点是父视图的左上角位置,如图所示:![视图坐标系](http://img.blog.csdn.net/20161126153620295)通过对这两种试图的了解,相信对之前的代码应该没有什么疑问了。
0 0
原创粉丝点击