android ontouchevent,Android OnTouchEvent()什么时候该 return super.onTouchEvent(event)?

自定义View在构造器初始化时设置了一个OnClickListener的监听器,但是如果在OnTouchEvent() 中返回true就没有办法回调onClick()?

// 一个简单的自定义View,让View跟随手指滑动,同时点击时弹出Toast

public class DragView2 extends View implements View.OnClickListener {

private static final String TAG = "DragView";

private float mLastX;

private float mLastY;

public DragView2(Context context) {

this(context, null);

}

public DragView2(Context context, AttributeSet attrs) {

this(context, attrs, 0);

}

public DragView2(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

setBackgroundColor(getResources().getColor(R.color.colorPrimary));

Log.d(TAG, "DragView2: ");

setOnClickListener(this);

}

@Override

public boolean onTouchEvent(MotionEvent event) {

int offsetX = (int) (event.getX() - mLastX);

int offsetY = (int) (event.getY() - mLastY);

switch (event.getAction()) {

case MotionEvent.ACTION_MOVE:

//  使View本身开始移动

offsetLeftAndRight(offsetX);

offsetTopAndBottom(offsetY);

break;

case MotionEvent.ACTION_UP:

mLastX = event.getX();

mLastY = event.getY();

break;

}

// return true 无法触发点击事件;return false时无法发生滑动 ;

// return super.onTouchEvent(event);才能触发这两个事件

// 为什么?

return super.onTouchEvent(event);

}

@Override

public void onClick(View v) {

Log.d(TAG, "onClick: ");

Toast.makeText(getContext(), "onClick", Toast.LENGTH_SHORT).show();

}

}

返回true 不是表示此触摸事件已被消化,为何只有

return super.onTouchEvent(event);

,才能同时保留滑动和点击事件?

OnClickListener.onClick()

是在原生的

View.onTouchEvent()

方法里面回调的, 你自己重写了这个方法, 而且不调用

super.onTouchEvent(event)

的话当然就不会回调

onClick()

方法了.

onClick方法是在onTouchEvent方法里调用的。你可能不理解重写的意义,你不使用super调用父类的onTouchEvent方法?onClick是不会得到执行的。

还有,你可能也不理解事件分发机制,我不相信一个不理解事件分发的程序猿能够自定义View。关于事件分发可以参考以下文章:http://m.blog.csdn.net/articl…

950-390_%E7%94%BB%E6%9D%BF-1.jpg

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Kotlin 中,实现 Android onTouchEvent 中指定某一个控件之外的区域点击事件与 Java 中类似,可以参考以下方法: 1. 在控件的 `onTouchEvent` 方法中判断点击的位置是否在指定控件之外的区域。如果是,则处理该事件并返回 `true` 表示已经处理完毕;否则返回 `super.onTouchEvent(event)`,让事件继续向下传递。 ```kotlin override fun onTouchEvent(event: MotionEvent?): Boolean { if (!isTouchInsideView(event, mTargetView)) { // 处理指定控件之外的事件 return true } return super.onTouchEvent(event) } private fun isTouchInsideView(event: MotionEvent?, view: View): Boolean { val location = IntArray(2) view.getLocationOnScreen(location) val x = location[0] val y = location[1] val width = view.width val height = view.height return event?.rawX ?: 0 >= x && event?.rawX ?: 0 <= x + width && event?.rawY ?: 0 >= y && event?.rawY ?: 0 <= y + height } ``` 2. 在自定义的 `ViewGroup` 中,重写 `onInterceptTouchEvent` 方法,根据点击的位置是否在指定控件之外的区域,判断是否需要拦截事件。如果需要拦截事件,则返回 `true`;否则返回 `super.onInterceptTouchEvent(event)`,让事件继续向下传递。 ```kotlin override fun onInterceptTouchEvent(event: MotionEvent?): Boolean { if (!isTouchInsideView(event, mTargetView)) { // 处理指定控件之外的事件 return true } return super.onInterceptTouchEvent(event) } private fun isTouchInsideView(event: MotionEvent?, view: View): Boolean { val location = IntArray(2) view.getLocationOnScreen(location) val x = location[0] val y = location[1] val width = view.width val height = view.height return event?.rawX ?: 0 >= x && event?.rawX ?: 0 <= x + width && event?.rawY ?: 0 >= y && event?.rawY ?: 0 <= y + height } ``` 需要注意的是,如果您拦截了指定控件之外的区域的点击事件,可能会影响用户的体验,因此建议仅在必要时使用此功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值