期间无意看到了饿了吗大神写的UETools工具,感觉很神奇,于是就翻了下代码看看如何做的,下面是源码浅析,自己也试着写了下相关代码封装了一个适合自己用的库,如有不对请在评论区留言指出,谢谢!
这里我只是浅析了下UETools代码是如何实现的,如果想看饿了吗大神UETools的源码,请移步https://github.com/eleme/UETool
饿了吗这个库主要是实现当前界面view基本信息的展示效果,当时很好奇是如何拿到当前界面view信息的,这里我们反推一下,想要获取某一个view信息------>要先拿到这个view------>可以先拿到当前界面所有views-------->根据手指位置来作为条件,从所有views中筛选出来这个view
- 这里有2个问题,如何拿到所有的views呢?
- 如何根据位置从views中筛选你手指处的view?
1.1我们先来解决第一个问题,拿到所有的views.
直接根据当前Activity,利用反射拿到当前界面所有的views,因为我们要根据onTouchEvent(MotionEvent event)获取位置,然后拿到目标view还要进行信息展示,这些代码写在一个新的Activity中,反射获取views核心代码如下:
这里只说5.0以及以上系统,低于版本系统不讨论,有兴趣研究下代码即可,在android.view.WindowManagerGlobal这个类中,有个成员变量mRoots,我们来看一下
所以我们反射拿到mRoots,进而拿到mViews集合,然后进行递归循环找到所有ViewGroup和View,就可以很快拿到所有的views的集合了.
将目标界面所有的View以及ViewGroup全部添加到List中,为了方便为所有view以及ViewGroup封装了一层壳叫Element,后面操作view就是操作Element的事情.
1.2 第二个问题,根据位置手指当前位置从views中筛选我们想要的指定view.
我们可以通过onTouchEvent(MotionEvent event)即可拿到手指当前位置,可是如何我们知道位置如何确定这个位置下的view呢?
Android里面有这样一个类:android.graphics.Rect
四个参数意义是什么呢?
那与手指触摸的位置有什么关系,我们关心的是如何定位到view,那么有一个api可以帮助我们
具体实现看关键代码
现在拿到event.getX(),event.getY(),以后查找view的关键代码在Element getTargetElement(float x, float y)中,看下详细代码:
代码核心是rect.contains(float x,float y),来查找当前手指对应的坐标点下的view,OK那我们现在可以根据手指位置获取到view了.那么view的信息你也可以拿到了,那么剩下的事情就是创建布局展示的事情了不用多说,简单看下.
可以看到,element.getView()得到了目标view,紧接着就可以拿到相关属性,这里有个问题,这个view可以是TextView,ImageView,YourCustomeView…,但是常用的就是TextView,ImageView,对于目前就以这2种常见view为主,其他view只是展示它的通用属性,特有属性暂时不予展示.
2 如何进行view拖拽来看位置变换后的效果
还是像上面一样反推一下:先定位到这个view对他进行做事情----->拖拽其实就是改变位置,改变位置我们常常重新设置LayoutParams来处理,这里我们用属性动画的view.setTranslationX(float x)和 view.setTranslationY(float y)来改变view的位置.来看下核心代码实现过程:
这里我只是浅析了下UETools代码是如何实现的,如果想看饿了吗大神UETools的源码,请移步https://github.com/eleme/UETool