Skip to content

Instantly share code, notes, and snippets.

@lesleh
Last active August 29, 2015 14:00
Show Gist options
  • Save lesleh/11189372 to your computer and use it in GitHub Desktop.
Save lesleh/11189372 to your computer and use it in GitHub Desktop.
An implementation of ImageView for Android that restricts the image to a given aspect ratio, if possible. This is a more generalised way of doing SquareImageView, just set both the width and height ratios to 1 for a square image.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="RatioImageView">
<attr name="width_ratio" format="float"/>
<attr name="height_ratio" format="float"/>
</declare-styleable>
</resources>
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.widget.ImageView;
public class RatioImageView extends ImageView {
private static final float DEFAULT_WIDTH_RATIO = 1;
private static final float DEFAULT_HEIGHT_RATIO = 1;
private float widthRatio = DEFAULT_WIDTH_RATIO;
private float heightRatio = DEFAULT_HEIGHT_RATIO;
public RatioImageView(Context context) {
super(context);
init(context, null, 0);
}
public RatioImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs, 0);
}
public RatioImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context, attrs, defStyle);
}
private void init(Context context, AttributeSet attrs, int defStyle) {
if(attrs == null)
return; // Nothing to do here
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.RatioImageView, 0, 0);
try {
widthRatio = a.getFloat(R.styleable.RatioImageView_width_ratio, DEFAULT_WIDTH_RATIO);
heightRatio = a.getFloat(R.styleable.RatioImageView_height_ratio, DEFAULT_HEIGHT_RATIO);
} finally {
a.recycle();
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
if(widthMode == MeasureSpec.EXACTLY && heightMode != MeasureSpec.EXACTLY) {
// Use the width
int width = widthSize;
int height = (int)Math.round(widthSize / widthRatio * heightRatio);
setMeasuredDimension(width, height);
} else if(heightMode == MeasureSpec.EXACTLY && widthMode != MeasureSpec.EXACTLY) {
// Use the height
int width = (int)Math.round(heightSize / heightRatio * widthRatio);
int height = heightSize;
setMeasuredDimension(width, height);
} else {
// ¯\(°_o)/¯
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
}
<!-- Fixes the image into a 4:3 ratio based on the width, also crops -->
<full.class.name.of.RatioImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/image"
android:scaleType="centerCrop"
app:width_ratio="4"
app:height_ratio="3"/>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment