判断点击事件发生在什么控件上

题目说的不是太清楚,具体说一下我的需求。

需求:做一个Android,SDK,被其他工程引用,不能重载View和实现OnClickListener或OnItemOClickListener,获取响应Click,onItemClick的控件。

两种思路:

1.使用AccessibilityService。

不可行的原因:

①只能获取点击事件,不能实现OnItemClick事件。

②用户必须手动到设置中允许用户使用,太繁琐。

2.在Activity中截获点击事件,根据MotionEvent,判断点击发生在屏幕中的那个控件上。

缺点:每点击一下,都要测算,会产生大量的冗余。手机性能好还没问题,手机如果垃圾就惨啦。那位大仙有别的方法,麻烦你告知小弟一下,在这里先谢谢了。

下面是实现的第二种方法的思路:

1.遍历根目录中的子控件,如果某个子控件区域包含点击坐标,停止根目录的子控件的判断,递归调用先前找的子控件,直到遍历结束。

2.如果遍历最后一层视图结束时,ViewGroup中没有找到子控件,就返回ViewGroup。

需要特别说明的是 MontionEvent 获取坐标有两种方式

1.event.getX(),event.getY().这种方法获取的是点击控件相对父控件的坐标,简言之就是视图坐标。

2.event.getRawX(),event.getRawY().获取的是绝对坐标,即是在屏幕上的坐标。

我们只能用第二种方法判断。

package com.alipay.tracker.click;

import android.os.AsyncTask;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import com.alipay.tracker.constant.TrackerLog;
import com.alipay.tracker.util.TrackerHelper;

public class GetClickAsyTask extends AsyncTask<Object, Void, Boolean> {

    @Override
    protected Boolean doInBackground(Object... params) {
        View view = (View) params[0];
        MotionEvent event = (MotionEvent) params[1];

        View view2 = isClicked(view, event);
        view.setTag(view2);
        TrackerLog.e("ClickView",view2.getClass().getSimpleName());

        return null;
    }

    private View isClicked(View view, MotionEvent event) {
        View result = null;
        if (inRangeOfView(view, event) && view.getVisibility() == View.VISIBLE) {
            if (view instanceof ViewGroup) {
                ViewGroup group = (ViewGroup) view;
                for (int i = 0; i < group.getChildCount(); i++) {
                    View chilView = group.getChildAt(i);
                    result = isClicked(chilView, event);
                    if (result != null) {
                        return result;
                    }
                }
            }
            result = view;
        }
        return result;
    }

}


 public static boolean inRangeOfView(View view, MotionEvent ev) {
        int[] location = new int[2];
        view.getLocationOnScreen(location);
        int x = location[0];
        int y = location[1];
        if (ev.getRawX() < x || ev.getRawX() > (x + view.getWidth()) || ev.getRawY() < y
            || ev.getRawY() > (y + view.getHeight())) {
            return false;
        }
        return true;
    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值