关于onTouchEvent的经验总结

时间:2022-09-30 19:55:31

关于onTouchEvent的经验总结

* 一直以来,虽然对onTounch事件了解的不是很透彻,但没影响到正常使用。恰巧今天搞了点自定义滑动开关,问题来了,卡了半晚上,最后终于搞定,于是写下这篇分享,希望大家引以为戒。*

直接上核心代码(好菜的说…)

第一次的代码: float startX = 0 在事件内部定义

    @Override
public boolean onTouchEvent(MotionEvent event) {
// TODO 设置滑动事件
float startX = 0 ;// 内部定义开始位置的坐标
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (startX == 0) {
startX = event.getRawX();
System.out.println("按下了。。。。" + startX);
}

break;
case MotionEvent.ACTION_MOVE:
float endX = event.getRawX();
float diff = endX - startX;
System.out.println("----> endX" + endX);
// System.out.println( " ----->"+ diff );
value += diff;
System.out.println(startX + "---->" + diff + "------------->"
+ value);
if (value > maxValue) {
value = maxValue;
} else if (value < 0) {
value = 0;
}

invalidate();
startX = event.getRawX();
System.out.println("新获取到的值" + startX);
break;
case MotionEvent.ACTION_UP:
//startX = 0;
break;

}
return true;
}

当时这段代码运行的结果是,自定义的开关,可以往右拖动,但是不能往左拖动

第二次把所有的上边的三个getRawX()换成 getX()

之后,可以完成左右拖动,但是 滑块不能实时移动,也就是说 滑块在鼠标拖动一段距离后才开始移动

第三次的代码好现在把内部定义开始位置坐标的 float startX 挪到方法外边

float startX = 0 ;// 外部定义开始位置的坐标
@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO 设置滑动事件
//float startX = 0 ;// 内部定义开始位置的坐标
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (startX == 0) {
startX = event.getRawX();
System.out.println("按下了。。。。" + startX);
}

break;
case MotionEvent.ACTION_MOVE:
float endX = event.getRawX();
float diff = endX - startX;
System.out.println("----> endX" + endX);
// System.out.println( " ----->"+ diff );
value += diff;
System.out.println(startX + "---->" + diff + "------------->"
+ value);
if (value > maxValue) {
value = maxValue;
} else if (value < 0) {
value = 0;
}

invalidate();
startX = event.getRawX();
System.out.println("新获取到的值" + startX);
break;
case MotionEvent.ACTION_UP:
//startX = 0;
break;

}
return true;
}

好吧终于成功了。

分析下失败的原因:

onTouch事件机制是,响应结束后重新进入新的响应,这个怎么理解呢? 比如说,按下时,响应按下事件,此时这个事件已经被消化,手指再移动时,重新进入一个新的touch事件。

所以,根据这个规律来看一看第一次失败的原因。首先再次普及一下getX()与getRawX()的区别

getX()是表示view相对于自身左上角的x坐标,而getRawX()是表示相对于屏幕左上角的x坐标值(注意:这个屏幕左上角是手机屏幕左上角,不管activity是否有titleBar或是否全屏幕)

第一次,得到的是绝对位置,因为设置这个自定义控件是居中的,所以getRawX()得到的值已经超过图片本身可以移动的长度,所以只能实现往右边滑动

第二次,得到的是相对位置,因为上下个图层,因为事件重新被激发,获取到的startX一直是零,当相对位置小到0时,才开始往左移动,0是小框的左侧边界位置,