ImageView的adjustViewBounds不工作

我有一个ImageView android:layout_width=100dpandroid:layout_height=wrap_contentandroid:adjustViewBounds=true

它的来源是一个50×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> 

Solutions Collecting From Web of "ImageView的adjustViewBounds不工作"

问题是adjustViewBounds 不会增加超出drawable自然尺寸的ImageView 的大小 。 只会缩小维持宽高比的观点; 如果您提供500×500的图像,而不是50×50的图像,这应该工作。

如果您对实现此行为的位置感兴趣,请参阅ImageView.java的onMeasure实现 。

一种解决方法是实现一个自定义的ImageView ,在onMeasure中改变这种行为。

有一个更简单的方法。 让你的ImageView像这样:

 <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="fitCenter" android:adjustViewBounds="true"/> 

通过保持高宽比,这种可绘制的方式将适用于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); } 

除了@ RomanNurik的回答

您可以在这里find工作解决scheme,可以复制粘贴代码或者添加Gradle依赖项

 dependencies { compile 'com.inthecheesefactory.thecheeselibrary:adjustable-imageview:1.0.1' } 

由@Nilzor提供的PS解决scheme不适合我

我有类似的要求; 在我的情况下,我希望图像是正方形,并希望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); } }