我有一个带有android:layout_width=100dp
,android:layout_height=wrap_content
和android:adjustViewBounds=true
它的来源是50 x 50像素的图片。但不保留纵横比 - ImageView的高度为50px,而不是100px(即adjustViewBounds
不起作用)。如果我有一个200x200px的图片它可以工作 - 宽度和高度是100px。此代码生成100px宽和50px高的图片,但src图像是正方形:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ImageView
android:id="@+id/photo"
android:src="@drawable/icon"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:adjustViewBounds="true" />
</LinearLayout>
答案 0 :(得分:65)
问题在于adjustViewBounds
不会增加ImageView
的大小超出drawable的自然维度。它只会缩小视图以保持纵横比;如果您提供500x500图像而不是50x50图像,这应该可以。
如果您对实施此行为的地点感兴趣,请参阅ImageView.java's onMeasure implementation。
一种解决方法是实现在ImageView
中更改此行为的自定义onMeasure
。
答案 1 :(得分:11)
有一种更简单的方法。像这样制作你的ImageView:
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitCenter"
android:adjustViewBounds="true"/>
这样 drawable将通过保留拉伸以适合ImageView中心 纵横比。我们只需计算合适的高度即可使其成比例 所以我们没有任何空白:
private void setImageBitmap(Bitmap bitmap, ImageView imageView){
float i = ((float)imageWidth)/((float)bitmap.getWidth());
float imageHeight = i * (bitmap.getHeight());
imageView.setLayoutParams(new RelativeLayout.LayoutParams(imageWidth, (int) imageHeight));
imageView.setImageBitmap(bitmap);
}
答案 2 :(得分:2)
除了@ RomanNurik的answer
您可以找到工作解决方案here,复制粘贴代码或只添加Gradle依赖
dependencies {
compile 'com.inthecheesefactory.thecheeselibrary:adjustable-imageview:1.0.1'
}
P.S。 @Nilzor提供的解决方案对我不起作用
答案 3 :(得分:0)
我有类似的要求;在我的情况下,我希望图像是方形的,并希望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);
}
}
答案 4 :(得分:-1)
此行将为您完成android:scaleType =“ fitXY”