view获取坐标位置的坑

在处理动画和popupWindow等的时候,需要获取view的位置。
比如确定动画终点,popUpWindow显示的地方,需要相对于一个已知的view做一些偏移。比如在屏幕某个功能按钮上方显示一个帮助提示。
使用了getLocationOnScreen,可以方便的获取到view的坐标。

这里提两个坑吧

  • getLocationOnScreen获取到的值为(0,0)

情况是在进入页面的时候,需要同时显示popUpWindow。图方便,就直接在oncreate里面获取view的location ,此时获取出来的是(0,0)。
这个当时没有仔细想,稍微冷静想一些就能猜到是view还没加载完成就去获取位置,当然是0了。其实这个在android开发艺术探索里面也提到过得,讲view的measure那一章。

处理的方式有
1.activity/view#onWindowFocusChanged 会调用多次
2.view.post(Runable) 利用messageQueue的队列性质,等处理这个runable的时候,前面的message也已经处理完了,view也就初始化好了。
3.viewTreeObserver
4.略(和前面三种比起来没啥优势)

在写博客之前,用的是delay一会再获取宽高,当然也可以正确获取到位置信息。不过现在知道多余了,队列的先进先出嘛,这种情况就没必要delay了(写博客重新整理下思路还是蛮好的 哈哈)。

  • getLocationOnScreen获取到的Y值,设置给viwe时,比预想的要大一些。

int[] location = new int[2];
targetView.getLocationOnScreen(loaction);
animBtn.setX(location[0]);
animBtn.setY(location[1]);

此时会发现animBtn的x是targetView的x,但是y会大一些。导致的结果就是在animBtn最后的位置会在targetView的下面。
当时是在给项目改动画的时候发现这个问题的。对这块业务不太熟,也对动画坐标这块不太了解。导致直接在项目上搞得时候,出现的效果每一次都超出自己的预料。

反正我觉得n件不熟悉的事情交杂在一起处理,复杂度肯定不只是n倍。可能是n平方,甚至是指数爆炸增长!!!

这时候,可以尝试下分割。比如先写demo来理解技术,暂时把复杂的业务代码隔开。等理解了这个,再去搞下一个。

后面发现getLocationOnScreen获取到的坐标是相当于整个屏幕的(函数名说的这么清楚了 哈哈)。那么相对于整个屏幕就要包含actionBar和statusBar。view.setX和setY是相对于视图坐标系的。这个差不多是我们程序员可以操作的空间。状态栏不算在视图坐标系。如果没有使用noActionBar,那么actionBar也是不算在视图坐标系里面。

《view获取坐标位置的坑》 location与顶部的关系

这就解释了为何x是正确的,y总是要大一些。使用这种方式的时候,需要减去顶部的高度。

//伪代码
view.setY(getLoactionY- (statusBar+setNoActionBar?0:acionBar))
    原文作者:Dynamic_2018
    原文地址: https://www.jianshu.com/p/221b91ffffd1
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞