I'm having a problem with displaying my image.
I have an Image I want to display full screen. So I have this Imageview with match_parent and 20dp padding.
It looks good but when I apply rotation on it, it seems that the bounds of the view doesn't change and the image can get clipped out of the screen ! Totally don't want that to happen! How do I rescale the image so that the image also fits in the ImageView when its 90 degrees rotated.
This is my XML WITH rotation in it.
EDIT:
How to fix the bounds of the Image so the Text is aligned just above the image?
Another version of the RotatedImageView which rotation can be animated with a ViewPropertyAnimator
. The idea is the same, but the scaling is done in onDraw()
instead of onMeasure()
, so it does not need a layout pass each time.
In order to make the animation work, I had to hijack the update listener. If you want to use your own listener, don't forget to invalidate()
the view in onAnimationUpdate()
.
public class RotatedImageView2 extends ImageView {
...
constructors
...
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int beforeWidth = getMeasuredWidth();
int beforeHeight = getMeasuredHeight();
int max = Math.max(beforeWidth, beforeHeight);
// try to grow
setMeasuredDimension(getDefaultSize(max, widthMeasureSpec), getDefaultSize(max, heightMeasureSpec));
}
private final float[] values = new float[9];
@Override
protected void onDraw(Canvas canvas) {
Drawable d = getDrawable();
if (d == null) {
return;
}
int drawableWidth = d.getIntrinsicWidth();
int drawableHeight = d.getIntrinsicHeight();
if (drawableWidth <= 0 || drawableHeight <= 0) {
return;
}
double rotationRad = getRotation() / 180 * Math.PI;
double rotatedWidth = (Math.abs(Math.sin(rotationRad)) * drawableHeight
+ Math.abs(Math.cos(rotationRad)) * drawableWidth);
double rotatedHeight = (Math.abs(Math.cos(rotationRad)) * drawableHeight
+ Math.abs(Math.sin(rotationRad)) * drawableWidth);
int availableWidth = getMeasuredWidth();
int availableHeight = getMeasuredHeight();
float scale = (float) Math.min(availableWidth / rotatedWidth, availableHeight / rotatedHeight);
getImageMatrix().getValues(values);
setScaleX(scale / values[Matrix.MSCALE_X]);
setScaleY(scale / values[Matrix.MSCALE_Y]);
super.onDraw(canvas);
}
@Override
public void setRotation(float rotation) {
super.setRotation(rotation);
// force redraw
invalidate();
}
@Override
public ViewPropertyAnimator animate() {
// force redraw on each frame
// (a ViewPropertyAnimator does not use setRotation())
return super.animate().setUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
invalidate();
}
});
}
}
Use example :
<com.mypackage.RotatedImageView2
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:adjustViewBounds="true"
android:rotation="90"
android:scaleType="fitCenter"
android:src="@drawable/test" />
according to a research leading to this topic i wonder if @Sarge Borsch answer could work in your case.
Try setting
android:scaleType="centerInside"
android:adjustViewBounds="true"
If centerInside is not correct because you want display in center, maybe try to position the imageview instead of the image inside.
Another suggestion: your imageview is set on "wrap_content" and i don't know exactly the order of everything but maybe the problem comes because it rotates after calculating dimensions (because of wrap_content). I think it is a possibility because the screenshoot you put shows that the image is not even fitting the width. TL;DR : try to fix the imageview size (padding on activity + match_parent) instead of wrap content, in combination of "adjustViewBounds".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With