我们都经常用setOnClickListener、setOnLongClickListener、setOnTouchListener三种事件,但我没有注意布尔返回值的存在,导致无法实现一些功能,决定研究一下
首先给一个按钮设置三种事件,都返回false,一一打上log
button.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
Log.i("TAG", "onLongClick: ");//长按
return true;
}
});
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.i("TAG", "onClick: ");//点击
}
});
button.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.i("TAG", "ACTION_DOWN: ");//触摸按下
break;
case MotionEvent.ACTION_UP:
Log.i("TAG", "ACTION_UP: ");//触摸抬起
break;
}
return true ;
}
});
单击按下按钮,发现输出log
I/TAG: ACTION_DOWN//触摸按下
I/TAG: ACTION_UP: //触摸抬起
I/TAG: onClick: //点击
这个时候正常执行触摸和点击事件,再长按它
I/TAG: ACTION_DOWN://触摸按下
I/TAG: onLongClick://长按
I/TAG: ACTION_UP: //触摸抬起
I/TAG: onClick: //点击
三种事件都执行,并且这可以看出三种点击事件的执行顺序
接下来把setOnLongClickListener的返回值设为true
public boolean onLongClick(View v) {
Log.i("TAG", "onLongClick: ");
return true;
}
单击按钮正常输出log
I/TAG: ACTION_DOWN://触摸按下
I/TAG: ACTION_UP: //触摸抬起
I/TAG: onClick: //点击
长按
I/TAG: ACTION_DOWN://触摸按下
I/TAG: onLongClick://长按
I/TAG: ACTION_UP: //触摸抬起
发现点击事件没有执行,如果我们给setOnTouchListener也返回true的话,同样长按---->这回只执行了触摸事件,这是为什么呢,决定从源码看起,点击源码后发现
* @return true if the callback consumed the long click, false otherwise.
*/
boolean onLongClick(View v);
关键注释:true if the callback consumed the long click ---->设置为true的话,只要执行了长按事件后,这个事件就被consumed(消费,这是一个过去式,所以是已经消费、销毁了haha)了,所以不再响应其他事件,并且由于点击事件的执行顺序为==setOnClickListener < setOnLongClickListener < setOnTouchListener==,所以结论如下。
结论:我们给setOnLongClickListener 设置true,比它后执行的setOnClickListener就不会被执行,如果给setOnTouchListener设置true,则setOnClickListener 、setOnLongClickListener 都不会执行,这个返回值控制的是执行完该事件后,是否销毁事件
by the way:如果给ImageView设置的触摸事件,如果返回false的话,只会执行ACTION_DOWN按下分支,并不会执行ACTION_UP抬起分支,如果两个都需要执行的话需要返回true