For whatever reason, setting the minHeight and maxHeight has no effect on the image dimension inside an ImageView component. In some cases, I end up with a VERY SMALL image. I presume this is due to the fact that I have the width and height set to "wrap_content" and "adjustViewBounds" set to true.
If I set "adjustViewBounds" to false, the image does expand to whatever I specify for minWidth and/or minHeight. However, in this case the image becomes distorted because its width and height are not scaled in proportion. I would like to avoid this situation too.
I end up writing a big chunk of code (as follows) to overwrite the onMeasure() method of ImageView. Is this really necessary?
public class FlexibleImageView extends ImageView {
private static final String LOG_TAG = "FlexibleImageView";
public FlexibleImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN) {
boolean adjustViewBounds = getAdjustViewBounds();
int minWidth = Math.max(getMinimumWidth(), getSuggestedMinimumWidth());
int minHeight = Math.max(getMinimumHeight(), getSuggestedMinimumHeight());
int maxWidth = getMaxWidth();
int maxHeight = getMaxHeight();
int widthSpec = getMeasuredWidth();
int heightSpec = getMeasuredHeight();
Drawable d = getDrawable();
if (d != null && adjustViewBounds) {
// Scale UP if the size is too small
float scale, scaleW = 1.0f, scaleH = 1.0f;
if (widthSpec < minWidth)
scaleW = (float) minWidth / (float) widthSpec;
if (heightSpec < minHeight)
scaleH = (float) minHeight / (float) heightSpec;
scale = (scaleW > scaleH) ? scaleW : scaleH;
if (scale > 1.0) {
int targetW = (int) Math.ceil(widthSpec * scale);
int targetH = (int) Math.ceil(heightSpec * scale);
Log.d(LOG_TAG, "Measured dimension (" + widthSpec + "x" + heightSpec
+ ") too small. Resizing to " + targetW + "x" + targetH);
// Make sure targetW, targetH stays within the bounds of maxW, maxH
if(targetW > maxWidth) {
targetH = targetH * maxWidth / targetW;
targetW = maxWidth;
Log.d(LOG_TAG, "Capping width to " + maxWidth);
}
if(targetH > maxHeight) {
targetW = targetW * maxHeight / targetH;
targetH = maxHeight;
Log.d(LOG_TAG, "Capping height to " + maxHeight);
}
setMeasuredDimension(targetW, targetH);
}
}
}
}
}
And XML portion:
<cards.myb.ui.FlexibleImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imageCard"
android:contentDescription="@string/card_image"
android:adjustViewBounds="true"
android:minHeight="@dimen/card_editor_img_min_dimen"
android:scaleType="fitXY"
android:src="@drawable/fb_logo" />