我想创建一个自定义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(...)
。