如何在自定义视图中访问layout_height属性?

11

我有一个自定义视图,我希望简单地访问xml布局中 layout_height 的值。

目前我在onMeasure期间获取并存储该信息,但仅在第一次绘制视图时发生。我的视图是XY图,需要尽早知道其高度以便开始执行计算。

该视图位于viewFlipper布局的第四页,因此用户可能要一段时间才能翻到该页面,但当他们翻到该页面时,我希望视图已经包含数据,这需要我有高度来进行计算。

谢谢!!!

4个回答

14

那行代码可以正常工作 :) ... 你需要将 "android" 替换为 "http://schemas.android.com/apk/res/android"

public CustomView(final Context context, AttributeSet attrs) {
    super(context, attrs);
    String height = attrs.getAttributeValue("http://schemas.android.com/apk/res/android", "layout_height");
    //further logic of your choice..
}

我尝试使用attrs.getAttributeValue("android","layout_width"),但它返回了null。然后我尝试了你的解决方案,它起作用了。谢谢! - Chris Sprague
但是,对于layoutDirection属性,它仍然对我返回null! - Mohammad Afrashteh

7
您可以使用这个:
public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);

    int[] systemAttrs = {android.R.attr.layout_height};
    TypedArray a = context.obtainStyledAttributes(attrs, systemAttrs);
    int height = a.getDimensionPixelSize(0, ViewGroup.LayoutParams.WRAP_CONTENT);
    a.recycle();
}

1
在获取高度后,调用a.recycle();非常重要。 - lpmfilho

5

public View(Context context, AttributeSet attrs) 构造函数文档中可以看出:

在从XML文件中填充视图时调用的构造函数。当从XML文件构建视图时,将调用此函数,并提供在XML文件中指定的属性。

因此,为了实现您的需求,请为自定义视图提供一个以属性为参数的构造函数,例如:

public CustomView(final Context context, AttributeSet attrs) {
    super(context, attrs);
    String height = attrs.getAttributeValue("android", "layout_height");
    //further logic of your choice..
}

2
命名空间应为“http://schemas.android.com/apk/res/android”(前面加上http://),否则高度将为空。 - Miloš Černilovský

4

Kotlin 版本

针对这个问题所给的答案并不能完全涵盖此问题,实际上它们是互相补充的。总结一下答案,首先我们应该检查 getAttributeValue 的返回值,然后如果 layout_height 定义为尺寸值,就使用 getDimensionPixelSize 来检索它:

val layoutHeight = attrs?.getAttributeValue("http://schemas.android.com/apk/res/android", "layout_height")
var height = 0
when {
    layoutHeight.equals(ViewGroup.LayoutParams.MATCH_PARENT.toString()) -> 
        height = ViewGroup.LayoutParams.MATCH_PARENT
    layoutHeight.equals(ViewGroup.LayoutParams.WRAP_CONTENT.toString()) -> 
        height = ViewGroup.LayoutParams.WRAP_CONTENT
    else -> context.obtainStyledAttributes(attrs, intArrayOf(android.R.attr.layout_height)).apply {
        height = getDimensionPixelSize(0, ViewGroup.LayoutParams.WRAP_CONTENT)
        recycle()
    }
}

// Further to do something with `height`:
when (height) {
    ViewGroup.LayoutParams.MATCH_PARENT -> {
        // defined as `MATCH_PARENT`
    }
    ViewGroup.LayoutParams.WRAP_CONTENT -> {
        // defined as `WRAP_CONTENT`
    }
    in 0 until Int.MAX_VALUE -> {
        // defined as dimension values (here in pixels)
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接