Android的 - 最初的布局后的反应布局、最初、反应、Android

2023-09-07 11:22:43 作者:被判无妻徒刑

这个问题已经被问了几次以各种形式,但我还没有找到一个明确的答案。

This question has been asked several times in various forms but I haven't found a definitive answer.

我需要能够获得的尺寸和后代的位置浏览容器的初始布局(后内容查看)。在这种情况下所需要的尺寸的视图(集团)不是predictable - 可能有多个行文字,最低高度,以适应装潢等。我不想做每一个在每一个布局传递( onLayout )。我所需要的测量是从一个深度嵌套的孩子,所以覆盖 onLayout / onMeasure 每个容器之间似乎一个糟糕的选择。我不会做任何会导致一个循环(触发事件时事件)。

I need to be able to get dimensions and positions of descendant Views after the initial layout of a container (a contentView). The dimensions required in this case are of a View(Group) that is not predictable - might have multiple lines of text, minimum height to accommodate decoration, etc. I don't want to do it every on every layout pass (onLayout). The measurement I need is a from a deeply nested child, so overriding the onLayout/onMeasure of each container in between seems a poor choice. I'm not going to do anything that'll cause a loop (trigger-event-during-event).

罗曼盖伊暗示,一旦我们可以只。员额 A 的Runnable 在查看(其中AFAIK将在UI线程)。这似乎在大多数设备的工作(3的4我有亲身),但未能在Nexus S.看起来Nexus S的没有尺寸的一切,直到它完成每个儿童一通,并没有正确的尺寸当 ED 的Runnable 被调用执行方法。我试着计算布局通行证(在 onLayout ),并比较 getChildCount ,这又适用于3开出4,但不同的3(失败的DROID RAZR,这似乎只做一通 - 并获得所有测量 - 无论孩子的数量)。我想上面的(通常张贴的各种排列;张贴到处理程序;铸造的getContext()活动并调用 runOnUiThread ...相同的结果全部)。

Romain Guy hinted once that we could just .post a Runnable in the constructor of a View (which AFAIK would be in the UI thread). This seems to work on most devices (on 3 of the 4 I have personally), but fails on Nexus S. Looks like Nexus S doesn't have dimensions for everything until it's done one pass per child, and does not have the correct dimensions when the posted Runnable's run method is invoked. I tried counting layout passes (in onLayout) and comparing to getChildCount, which again works on 3 out of 4, but a different 3 (fails on Droid Razr, which seems to do just one pass - and get all measurements - regardless of the number of children). I tried various permutations of the above (posting normally; posting to a Handler; casting getContext() to an Activity and calling runOnUiThread... same results for all).

最后我用一个可怕的可耻无不错的黑客,通过检查其父母的身高目标群体的高度 - 如果它是不同的,这意味着它已经奠定了。显然,不是最好的方法 - 但唯一一个似乎各种设备和实现之间的可靠地工作。我知道有没有内置的事件或回调,我们可以使用,但有没有更好的办法?

I ended up using a horrible shameful no-good hack, by checking the height of the target group against its parent's height - if it's different, it means it's been laid out. Obviously, not the best approach - but the only one that seems to work reliably between various devices and implementations. I know there's no built-in event or callback we can use, but is there a better way?

TYIA

/修改的底线我,我的猜测是,Nexus S的不等到布局时, .posting完成()一个的Runnable ,因为是我测试过的所有其它设备的情况下,和所建议的罗曼盖伊等。我还没有找到一个好的解决办法。有一?

/EDIT The bottom line for me I guess is that the Nexus S does not wait until after layout has completed when .posting() a Runnable, as is the case on all other devices I've tested, and as suggested by Romain Guy and others. I have not found a good workaround. Is there one?

推荐答案

我已经成功地使用OnGlobalLayoutListener。

I've been successful using the OnGlobalLayoutListener.

这真是棒极了我的Nexus S

It worked great on my Nexus S

final LinearLayout marker = (LinearLayout) findViewById(R.id.distance_marker);
OnGlobalLayoutListener listener = new OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        //some code using marker.getHeight(), etc.
        markersContainer.getViewTreeObserver().removeGlobalOnLayoutListener(this);
    }
};
marker.getViewTreeObserver().addOnGlobalLayoutListener(listener);