我创建了一个实现的自定义视图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( width / height > aspectRatio //too wide
&& (
widthMode == MeasureSpec.AT_MOST ||
widthMode == MeasureSpec.UNSPECIFIED
)
) {
width -= (width - height * aspectRatio);
}
if( width / height < aspectRatio //too tall
&& (
heightMode == MeasureSpec.AT_MOST ||
heightMode == MeasureSpec.UNSPECIFIED
)
) {
height -= (height - width / aspectRatio);
}
setMeasuredDimension((int)width, (int)height);
}
nominalheight
目的是在可能的情况下创建一个长宽比与和指定的长宽比相同的矩形nominalwidth
。显然,如果函数被传递MeasureSpec.EXACTLY
,那么它应该以该方向给定的尺寸布局。
我在 xml 中在两个方向上都进行了View
布局。WRAP_CONTENT
让我感到困惑的是,通过 onMeasure 调用,其中一半显示 MeasureSpec.AT_MOST 并且例程计算正确的矩形,另一半显示 MeasureSpec.EXACTLY 并且它显然使用给定的尺寸。更令人费解的是,如果我禁用条件(我会假设,从文档和示例代码中错误地)它工作正常。
为什么我会收到这些具有不同值的交替调用,以及如何说服 Android 以正确的尺寸布置我的视图?