告诉 Android 布局会膨胀"wrap_content"应该有多大



我想创建一个自定义View,这样当它充气时,wrap_content作为维度参数之一,match_parent作为另一个维度参数,它将具有恒定的纵横比,填充设置为match_parent的任何维度,但提供布局膨胀与另一个维度一起"包装"。 我认为这是可能的,因为,例如,全屏宽度TextView显然能够要求它有两行、三行或任何任意数量的文本的空间(取决于宽度(,但直到通货膨胀时间才必然知道这一点。

理想情况下,我想做的是覆盖View子类中的布局方法,以便在视图膨胀时,我获取布局信息,并为要包装的"内容"提供自己的尺寸(即我的固定比率矩形(。

我需要创建很多这样的自定义视图,并将它们放在各种不同类型的布局中——有时使用Adapter——所以真的,我希望最大限度地控制它们的通货膨胀。 这样做的最佳技术是什么?

您始终可以在 onMeasure 中检查是否符合纵横比。

我知道这不是一个完整的答案,但它应该引导你到那里;)

我现在用以下代码解决了这个问题。 值得一提的是,我覆盖的类是带有自定义子项的自定义ViewGroup,所有这些都使用继承的onMeasure。 子项是在施工时创建和添加的,我认为这是理所当然的。

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    float width = MeasureSpec.getSize(widthMeasureSpec);
    final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
    float height = MeasureSpec.getSize(heightMeasureSpec);
    final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
    float nominalHeight = getResources().getInteger(R.integer.nominalheight);
    float nominalWidth = getResources().getInteger(R.integer.nominalwidth);
    float aspectRatio = nominalWidth / nominalHeight;
    if( widthMode == MeasureSpec.UNSPECIFIED ) { //conform width to height
        width = height * aspectRatio;
    }
    else if (heightMode == MeasureSpec.UNSPECIFIED ) { //conform height to width
        height = width / aspectRatio;
    }
    else if( width / height > aspectRatio //too wide
            && ( widthMode == MeasureSpec.AT_MOST )
            ) { 
        width -= (width - height * aspectRatio);
    }
    else if( width / height < aspectRatio //too tall
            && ( heightMode == MeasureSpec.AT_MOST )
            ) { 
        height -= (height - width / aspectRatio);
    }
    int newWidthMeasure = MeasureSpec.makeMeasureSpec((int)width, MeasureSpec.AT_MOST);
    int newHeightMeasure = MeasureSpec.makeMeasureSpec((int)height, MeasureSpec.AT_MOST);
    measureChildren(newWidthMeasure, newHeightMeasure);
    setMeasuredDimension((int)width, (int)height);
}

我根据资源中的名义矩形来定义纵横比,但显然还有很多其他方法可以做到这一点。

感谢约瑟夫斯·维拉雷(Josephus Villarey(首先向我指出onMeasure(...)

最新更新