自定义View(三):View的触摸与滑动
1、Android的坐标轴
android的坐标轴是以屏幕的左上角为原点,水平向右为x轴正方向,垂直向下为y轴正方向。View有一套方法来获取自身的位置。
getLeft():获取View最左边在父布局中的位置
getRight():获取View最右边在父布局中的位置
getTop():获取View最上边在父布局中的位置
getBottom():获取View最下边在父布局中的位置
2、View的触摸与滑动要用到那些方法
当View被触摸会时调用onTouchEvent(MotionEvent event)方法,滑动时则需要利用layout()方法来重新定位View的位置,以达到滑动的效果。
首先我们来研究一下onTouchEvent(MotionEvent event)方法,我们知道触摸常常有三种方式:触摸屏幕、在屏幕上拖动、触摸点离开屏幕,我们可以通过MotionEvent的getAntion来判断。
MotionEvent.ACTION_DOWN:触摸屏幕
MotionEvent.ACTION_MOVE:在屏幕上拖动
MotionEvent.ACTION_UP:触摸点离开屏幕
3、重写onTouchEvent方法
新建MyView类继承View类并实现他的四个构造方法,重写onTouchEvent方法,代码如下:
@Override public boolean onTouchEvent(MotionEvent event) { int x= (int) event.getX();//获取触摸位置 int y= (int) event.getY(); switch (event.getAction()){ //触摸屏幕 case MotionEvent.ACTION_DOWN: beginX=x; beginY=y; Log.w("debug","down_x:"+x+" down_y:"+y); break; //在屏幕上拖动 case MotionEvent.ACTION_MOVE: //计算拖动距离 int moveX=x-beginX; int moveY=y-beginY; Log.w("debug","move_x"+moveX+" move_y:"+moveY); break; //触摸离开屏幕 case MotionEvent.ACTION_UP: Log.w("debug","up_x"+x+" up_y:"+y); break; } return true; }
beginX和begin分别记录触摸屏幕时的位置,值得注意的是event.getX()和event.getY()都是根据View的左上角为原点,点击控件时在屏幕上拖动一小段距离可以看到如下运行结果:
4、通过layout()方法实现滑动
首先讲一下layout方法的参数
layout(int l, int t, int r, int b)
很显然要传的是View的新位置的四个坐标点。
l:View在父布局中最左边的坐标点
t:View在父布局中最上边的坐标点
r:View在父布局中最右边的坐标点
b:View在父布局中最下边的坐标点
滑动之后View的新位置为旧坐标+滑动的距离,View的滑动就实现了,上完整代码:
public class MyView extends View { private int beginX,beginY; public MyView(Context context) { super(context); } public MyView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); } @Override public boolean onTouchEvent(MotionEvent event) { int x= (int) event.getX();//获取触摸位置 int y= (int) event.getY(); switch (event.getAction()){ //触摸屏幕 case MotionEvent.ACTION_DOWN: beginX=x; beginY=y; Log.w("debug","down_x:"+x+" down_y:"+y); break; //在屏幕上拖动 case MotionEvent.ACTION_MOVE: //计算拖动距离 int moveX=x-beginX; int moveY=y-beginY; layout(getLeft()+moveX,getTop()+moveY,getRight()+moveX,getBottom()+moveY); Log.w("debug","move_x"+moveX+" move_y:"+moveY); break; //触摸离开屏幕 case MotionEvent.ACTION_UP: Log.w("debug","up_x"+x+" up_y:"+y); break; } return true; } }
5、源码链接
https://github.com/Hasagit/LayoutDemo.git