onGlobalLayoutListener vs postRunnable

时间:2016-04-12 23:56:55

标签: android view lazy-loading runnable

我试图在完成活动加载后计算视图的x,y位置。我所做的是view.postDelayed(runnable, 2000),它正常工作。代码审阅者对此并不满意,并建议使用OnGlobalLayoutListener来了解活动加载的完成情况。不知何故,我不喜欢OnGlobalLayoutListener,因为它与我的解决方案不需要的整个视图树相关联。我试图了解这些方法的利弊。谢谢!

3 个答案:

答案 0 :(得分:2)

如果您要做的只是阅读视图的xy坐标,我建议您使用view.post(Runnable)毫无延迟(除非有充分理由包含延迟) 。这会将Runnable添加到UI线程中的消息队列中。 Runnable等待执行,直到View充气并附加到窗口后。由于View位置属性值取决于视图的布局上下文,因此发布Runnable将为您提供所需的时间。

正如您在问题描述中提到的,OnGlobalLayoutListener将适用于整个View的布局,如类名所示。只有在关注视图树中任何或所有视图的布局状态或可见性时,才应考虑OnGlobalLayoutListener。即任何导致视图树被重新布局的东西。

答案 1 :(得分:0)

代码审核者不满意,因为你等了2秒,然后猜测活动的加载完成了。这可能是您的模拟器或设备的情况,但在较旧和较慢的设备上,活动可能没有完成加载。为了100%安全,活动已经完成加载,你应该使用听众通知听众'加载完成后。

答案 2 :(得分:0)

我认为这样做的正确方法是在视图中添加onPreDrawListener。这是在即将绘制视图时调用的侦听器,以及已有关于它的大小(宽度和高度)和位置(X和Y)的所有信息。

示例:

final View v = new View(getContext());
        v.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
            @Override
            public boolean onPreDraw() {
                v.getViewTreeObserver().removeOnPreDrawListener(this);
                float myX = v.getX();
                float myY = v.getY();
                return true;
            }
        });

别忘了让onPreDraw上的方法返回true,我不知道为什么但是Android Studio会在创建监听器时返回false。 也不要忘记从视图中删除侦听器,否则可能会再次无用地调用。