我也有类似的要求;在我的例子中,我希望图像是正方形的,并且希望 ImageView 匹配纵横比,这样我就可以使用它的背景和填充来绘制边框。
我在这里阅读了答案,但我决定制作一个保证其内容(应该只有一个视图)是方形的布局,而不是覆盖 ImageView。这样我就可以在里面使用标准的 ImageView 了。 (你永远不会知道,我可能想稍后再做一些方形的东西。虽然可能不会。)
如果它对其他人有用,这里是代码(随意复制)。可能存在错误,因为我刚刚使它适用于我的应用程序然后停止了。 :)
public class SquareLayout extends ViewGroup
{
public SquareLayout(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
}
public SquareLayout(Context context, AttributeSet attrs)
{
super(context, attrs);
}
public SquareLayout(Context context)
{
super(context);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b)
{
// Work out width and height, and square size.
int width = r - l;
int height = b - t;
int size, xOffset, yOffset;
if(width < height)
{
size = width;
xOffset = 0;
yOffset = (height - size) / 2;
}
else
{
size = height;
xOffset = (width - size) / 2;
yOffset = 0;
}
for(int i = 0; i < getChildCount(); i++)
{
View child = getChildAt(i);
child.layout(xOffset, yOffset, size + xOffset, size + yOffset);
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
// Get width and height.
int w = -1, h = -1;
switch(MeasureSpec.getMode(widthMeasureSpec))
{
case MeasureSpec.AT_MOST:
case MeasureSpec.EXACTLY:
w = MeasureSpec.getSize(widthMeasureSpec);
break;
case MeasureSpec.UNSPECIFIED:
break;
}
switch(MeasureSpec.getMode(heightMeasureSpec))
{
case MeasureSpec.AT_MOST:
case MeasureSpec.EXACTLY:
h = MeasureSpec.getSize(heightMeasureSpec);
break;
case MeasureSpec.UNSPECIFIED:
break;
}
// If only one of width/height is unspecified, set them both the same.
if(w == -1 && h != -1)
{
w = h;
}
else if(h == -1 && w != -1)
{
h = w;
}
// Either they're both specified or both unspecified.
int childMeasureSpec;
if(w == -1)
{
childMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
}
else
{
childMeasureSpec = MeasureSpec.makeMeasureSpec(w, MeasureSpec.EXACTLY);
}
// Pass through to children.
int maxDimension = 1;
for(int i = 0; i < getChildCount(); i++)
{
View child = getChildAt(i);
child.measure(childMeasureSpec, childMeasureSpec);
maxDimension = Math.max(maxDimension, child.getMeasuredWidth());
maxDimension = Math.max(maxDimension, child.getMeasuredHeight());
}
if(w == -1)
{
w = maxDimension;
h = maxDimension;
}
setMeasuredDimension(w, h);
}
}