以编程方式获取在 xml 布局中设置为 wrap_content 的视图维度

Programmatically get a view's dimension that's been set to wrap_content in the xml layout

对于下拉动画,我需要获取已设置为 wrap_content 的视图的实际 dp 高度,因此取决于其包含的意见。 代码示例显示了我需要知道高度的 LinearLayout,在高度为 0 的相对布局内。动画应该将 RelativeLayout 的高度增加到内部 LinearLayout 的高度值:

<RelativeLayout
            android:id="@+id/new_device_wrpr"
            android:layout_width="wrap_content"
            android:layout_height="@dimen/zero_size"
            android:layout_alignLeft="@id/new_device_dd_button_knob"
            android:layout_below="@id/new_device_dd_button_knob" >
            <LinearLayout
                android:id="@+id/new_device_spawn"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@android:color/holo_orange_light"
                android:orientation="vertical" >
            </LinearLayout>
        </RelativeLayout>

仅如下所示的实现 returns 0:

LinearLayout lL = (LinearLayout) findViewById(R.id.new_device_knob_spawn);
            lL.getHeight();

getWidth()getHeight() 都可以,但这取决于 "WHEN" 你怎么称呼它!

如果您在 "onCreate" 事件中调用它,它总是 return 0(那是因为尚未测量视图)。

正如 Christian 所说,您需要等待布局发生,然后才能检索视图的大小。如果您尝试在 onCreate 中执行此操作,我建议您使用全局布局侦听器在布局完成后执行回调。

final LinearLayout lL = (LinearLayout) findViewById(R.id.new_device_knob_spawn);
lL.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        int h = lL.getHeight();
        // Do whatever you want with h
        // Remove the listener so it is not called repeatedly
        ViewHelper.removeOnGlobalLayoutListener(lL, this);
    }
});

为了不使用已弃用的方法,我使用了这个静态辅助方法来删除全局布局侦听器。这是由于 Jellybean 中的重命名方法。

public static void removeOnGlobalLayoutListener(View v, ViewTreeObserver.OnGlobalLayoutListener victim) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
        removeLayoutListenerJB(v, victim);
    } else removeLayoutListener(v, victim);
}

@SuppressWarnings("deprecation")
private static void removeLayoutListenerJB(View v, ViewTreeObserver.OnGlobalLayoutListener victim) {
    v.getViewTreeObserver().removeGlobalOnLayoutListener(victim);
}

@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
private static void removeLayoutListener(View v, ViewTreeObserver.OnGlobalLayoutListener victim) {
    v.getViewTreeObserver().removeOnGlobalLayoutListener(victim);
}