Android中onTouch事件和onClick事件冲突问题解决

文章介绍了在Android开发中,如何处理一个悬浮按钮同时实现长按拖动和点击跳转的需求。通过重写OnTouchListener,当检测到ACTION_DOWN、ACTION_MOVE和ACTION_UP时,判断是否有移动来区分点击和拖动事件,避免事件冲突。通过设置一个标记变量hasMoved,当移动距离超过一定阈值时标记为移动,否则视为点击,提高了用户体验。
摘要由CSDN通过智能技术生成

需求再现

最近在开发这样一个需求:做一个悬浮的按钮,长按可以拖动按钮移动,点击要能跳转。

需求分析

点击事件处理,使用View.OnClickListener事件处理即可;
拖动功能需要重写View.OnTouchListener事件即可;
开始代码大致如下:

View movedButton; //需要移动的按钮
movedButton.setOnClickListener(new View.OnClickListener(){
	@Override
    public void onClick(View v) {
    	//在这里处理点击跳转
    }
});
movedButton.setOnTouchListener(new View.OnTouchListener(){
	@Override
    public boolean onTouch(View v, MotionEvent event) {
		if (event.getAction() == MotionEvent.ACTION_DOWN) {

		}else if (event.getAction() == MotionEvent.ACTION_MOVE) {
			//处理移动
			v.offsetLeftAndRight(offsetX); 
            v.offsetTopAndBottom(offsetY); 
		}else if (event.getAction() == MotionEvent.ACTION_UP) {
	
		}
		return false;
	}
});

遇到的问题

在测试的过程中发现,按钮确实可以正常移动,可是每次移动都会触发按钮的点击事件,一瞬间我就想到了可能是事件冲突导致的,于是查看了一下View的源代码(此处不贴源代码了,只说明问题原因),发现onTouch事件是最先触发的,在MotionEvent.ACTION_UP的时候才触发了onClick事件及onLongClick事件。也就是说,需要在ACTION_UP的时候判定是否要消费此次事件,如果消费掉就返回true,那么就不会触发onClick事件了。

解决方案

我们可以设定一个布尔变量标记触摸事件过程中是否有移动即可,代码如下:

View movedButton; //需要移动的按钮
movedButton.setOnClickListener(new View.OnClickListener(){
	@Override
    public void onClick(View v) {
    	//在这里处理点击跳转
    }
});
movedButton.setOnTouchListener(new View.OnTouchListener(){
	@Override
    public boolean onTouch(View v, MotionEvent event) {
    	boolean hasMoved;
		if (event.getAction() == MotionEvent.ACTION_DOWN) {
			hasMoved = false;
		}else if (event.getAction() == MotionEvent.ACTION_MOVE) {
			//处理移动
			v.offsetLeftAndRight(offsetX); 
            v.offsetTopAndBottom(offsetY); 
            //注意:将小幅度的移动判定为点击事件,这样可以增加点击事件的灵敏度
            if(Math.abs(offsetX) > 5 || Math.abs(offsetY) > 5) {
                hasMoved = true;
            }
		}else if (event.getAction() == MotionEvent.ACTION_UP) {
			return hasMoved;
		}
		return false;
	}
});

小结一下

1、事件处理贯穿整个Android应用,使用过程中时刻牢记Android事件的处理机制,所有的事件都是用onTouch事件开始的。
2、本例子中,将小幅度的移动判定为点击事件,这样可以增加点击事件的灵敏度,体验会更好一些。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值