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

 自定义控件中,使自定义控件根据手势滑动而移动的实现方式有很多,这篇文章讲解通过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坐标系](https://img-blog.csdn.net/20161126152933582)
另一种坐标系是视图坐标系,它描述了子视图在父视图中的位置关系,在该坐标系下,原点是父视图的左上角位置,如图所示:
![视图坐标系](https://img-blog.csdn.net/20161126153620295)

通过对这两种试图的了解,相信对之前的代码应该没有什么疑问了。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值