以编程方式获取在 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);
}
对于下拉动画,我需要获取已设置为 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);
}