寻找屏幕上的点击位置--Queen核心技术分享
来源:互联网 发布:大数据云计算培训 编辑:程序博客网 时间:2024/05/22 17:07
APP发布之后,发布者最关心的事情自然是用户使用APP的情况。换言之,他们希望回答一个问题:我的用户是怎么使用我的APP的?为了回答这个问题,最重要的步骤就是用户数据收集,因为用户不可能来到你的身边去展示他对APP的使用方法。那么只能让数据来告诉你答案。
Queen的工作便是跟踪用户对APP的使用过程,其中,识别用户的操作是Queen的核心内容。用户对APP的动作包括点击,滑动等等。识别动作的思路自然可以是从控件上下功夫,因为用户的操作的直接对象便是控件。那么对于一个点击,自然可以通过以下方法去采集数据。
button.setOnClickListener(new View.OnClickListener(){ onClick(View v){ //插入数据采集接口 }})
但是,一个APP可能有成百个控件,甚至一个页面就有好几个。统统这样插入接口工作量巨大,所以并不是一个最优的方法。Queen的采集过程来自Android点击信号传递方式。总所周知,在Android中最先感知点击事件的是rootView,之后通过onInterceptTouchEvent()接口向子View传递该信息,直到消费该点击事件的view为止。之后onTouchEvent将该事件从子View向父View传递。
这个工作原理为我们抓取点击事件提供了线索,这里由于rootView包含了整个View上的所有控件,那么对于一个点击事件,我们只需要知道点击位置,然后依据点击位置,从rootView开始一层层去查最顶上的,可点击的时间就可以了。
详细代码请参考 https://github.com/chenqihong3/queen。
Queen的解决方案是这样子:
/** * 识别在View上所进行的动作 * Get the operation on the view. * * @param ev 动作; Operation; * @param myView 执行动作的View; View on the screen; * @param context */public void recognizeViewEvent(MotionEvent ev, View myView, Context context){switch(ev.getAction()){ case MotionEvent.ACTION_DOWN:{ try{//... ... final float pressX = ev.getRawX(); //点击位置X final float pressY = ev.getRawY(); //点击位置Y findViewAtPosition(myView, (int)pressX, (int)pressY);//找到点击的控件 if(mViewStack.isEmpty()){ return; } }catch(Exception e){Log.e(TAG, "recognizeViewEvent: unknown error"); } break; } case MotionEvent.ACTION_UP:{ //... ... final float x = ev.getRawX(); final float y = ev.getRawY(); findViewAtPosition(myView, (int)x, (int)y); //找到点击控件 try{if(view instanceof CheckBox){//收集控件信息}else if(view instanceof Button){ //收集控件信息 }else if(view instanceof ImageView){ //收集控件信息 }else if(view instanceof TextView){ //收集控件信息 }else{ } }catch(Exception e){Log.e(TAG, "recognizeViewEvent: unknown error"); } } break; }}
Queen第一步便是识别点击的动作ACTION_DOWN和ACTION_UP,只有两个动作所消费的对象是同一个控件时,此点击才能算是一次完整的点击,然后获取点击位置的x, y。第二步便是根据位置x,y查找相应的View,即findViewAtPosition(View, int, int)方法的调用,找到相应的View以后便进行View的控件类型判断,输出结果。接下来我们看看findViewAtPosition方法都做了一些什么:
/** * 通过用户动作的范围查找相应的View * find view that the user interacts. * * @param parent 最上层View * @param x 动作触摸点x坐标 * @param y 动作触摸点y坐标 */ private void findViewAtPosition(View parent, int x, int y) { int length = 1; Rect rect = new Rect(); parent.getGlobalVisibleRect(rect); if(parent instanceof ViewGroup){ length = ((ViewGroup)parent).getChildCount(); } for (int i = 0; i < length; i++) { if(parent instanceof ViewGroup){ if(View.VISIBLE == parent.getVisibility()){ View child = ((ViewGroup) parent).getChildAt(i); findViewAtPosition(child, x, y); } } else { if (rect.contains(x, y)) { if(View.VISIBLE == parent.getVisibility() && parent.isClickable()){ mViewStack.push(parent); } } } } if(parent.isClickable() && rect.contains(x, y) && View.VISIBLE == parent.getVisibility()){ mViewStack.push(parent); } }
在这个方法中,从根View开始,我们一步步搜索被点击的View,首先确定点击范围rect,然后判断该View是不是ViewGroup,如果是,获取其中包含的子View并对每个子View进行迭代搜索,对于每个子View,我们确定该View是不是点击,同时确定该view是不是在rect点击范围,以及是否可见,最终将符合标准的View放入ViewStack。
通过以上两个方法,Queen一步一步找到用户点击的控件,并记录一条动作信息。这就是Queen寻找屏幕上被点击控件的方法。
详细代码请参考:https://github.com/chenqihong3/queen
- 寻找屏幕上的点击位置--Queen核心技术分享
- android view 屏幕的点击位置分析
- Android获取点击屏幕的位置坐标
- ios获取点击屏幕的位置
- 如何获取点击屏幕的位置
- 获取屏幕位置、高度和在屏幕上的位置
- 得到光标在屏幕上的位置
- 捕获鼠标位置[在屏幕上的位置]
- 点击cell上的button 获取点击的位置
- iOS 获取label上点击位置的字符位置
- Android adb shell 获得点击屏幕的位置坐标
- Android adb shell 获得点击屏幕的位置坐标
- Android adb shell 获得点击屏幕的位置坐标
- android上,实现直接在屏幕上显示点击位置,方便调试。
- Android自定义控件(特效一) 点击屏幕,根据所点击的位置绘制圆环
- Android自定义控件(特效二) 点击屏幕,根据所点击的位置绘制桃心
- Android自定义控件(特效一) 点击屏幕,根据所点击的位置绘制圆环
- Android自定义控件(特效二) 点击屏幕,根据所点击的位置绘制桃心
- ZOJ 3603Draw Something Cheat(模拟)
- codeforces--623C The Smallest String Concatenation
- iOS开发多线程的理论介绍
- ORA-00257: archiver error --11GR2 RAC 设置归档路径和开启flashback
- Hibernate连接MySQL
- 寻找屏幕上的点击位置--Queen核心技术分享
- Unity3D与android交互---构建android插件
- Oracle知识点
- ZOJ 3607Lazier Salesgirl(greed)
- 遇见糟糕的自己
- JAVA解析JSON相关
- facebook 社会化分享 android部分
- React Native-16.React Native 常用API及实践 PixelRatio
- ZOJ 3609Modular Inverse(暴力)