I added several solution. If you want to rotate image on click btn and image size must be fill parent layout. You can also use https://github.com/rongi/rotate-layout and https://mcmap.net/q/136755/-android-imageview-rotation-animation-keep-scale-type-fit-center this code also works
ImageView photoView = findViewById(R.id.photo_view);
ImageView rotateBtn = findViewById(R.id.rotate_image);
FrameLayout photoFrame = dialogView.findViewById(R.id.photoFrame);
final float[] currentRotation = {0f};
final boolean[] isFirst = {true};
final boolean[] isInitial = {true};
final float[] firstWidth = {0};
final float[] firstHeight = {0};
final float[] secondWidth = {0};
final float[] secondHeight = {0};
rotate_image.setOnClickListener(view -> {
if (isInitial[0]) {
isInitial[0] = false;
firstWidth[0] = photoView.getWidth();
firstHeight[0] = photoView.getHeight();
float frameWidth = photoFrame.getWidth();
float frameHeight = photoFrame.getHeight();
if (firstHeight[0] >= firstWidth[0]) {
float imageRatio = firstHeight[0] / firstWidth[0];
if (frameHeight > frameWidth) {
secondWidth[0] = frameWidth;
secondHeight[0] = secondWidth[0] / imageRatio;
} else {
secondHeight[0] = frameHeight;
secondWidth[0] = secondHeight[0] * imageRatio;
}
} else {
float imageRatio = firstWidth[0] / firstHeight[0];
float frameRatio = frameHeight / frameWidth;
if (imageRatio >= frameRatio) {
secondHeight[0] = frameHeight;
secondWidth[0] = secondHeight[0] / imageRatio;
} else {
secondWidth[0] = frameWidth;
secondHeight[0] = secondWidth[0] * imageRatio;
}
}
}
float imageWidth = isFirst[0] ? secondWidth[0] : firstHeight[0];
float imageHeight = isFirst[0] ? secondHeight[0] : firstWidth[0];
isFirst[0] = !isFirst[0];
// You can use custom animation
//Animation rotateAnimation = new RotateAnimation(currentRotation,
//currentRotation -= 90, Animation.RELATIVE_TO_SELF, 0.5f,
//Animation.RELATIVE_TO_SELF, 0.5f);
//rotateAnimation.setDuration(100);
//rotateAnimation.setFillAfter(true);
//photoView.startAnimation(rotateAnimation);
photoView.animate().rotation(currentRotation[0] -= 90).start();
photoView.getLayoutParams().height = (int) imageWidth;
photoView.getLayoutParams().width = (int) imageHeight;
photoView.requestLayout();
});
My xml code below:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/photoFrame"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginVertical="10dp"
app:layout_constraintBottom_toTopOf="@+id/rotate_image"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" >
<ImageView
android:id="@+id/photo_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:src="@mipmap/ic_client_photo_nophoto" />
</FrameLayout>
<ImageView
android:id="@+id/rotate_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/rotate_image"
android:layout_marginBottom="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
I maked another solution without animation and it worked with image file:
ImageView photoView = findViewById(R.id.photo_view);
ImageView rotate_image = findViewById(R.id.rotate_image);
Glide.with(context)
.load(file)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(photoView);
rotate_image.setOnClickListener(view -> {
rotateImageFile(file.getPath());
Glide.with(context)
.load(file)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(photoView);
});
public void rotateImageFile(String imagePath) {
try {
ExifInterface exif = new ExifInterface(imagePath);
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
switch (orientation) {
case 1:
exif.setAttribute(ExifInterface.TAG_ORIENTATION, String.valueOf(ExifInterface.ORIENTATION_ROTATE_90));
break;
case 6:
exif.setAttribute(ExifInterface.TAG_ORIENTATION, String.valueOf(ExifInterface.ORIENTATION_ROTATE_180));
break;
case 3:
exif.setAttribute(ExifInterface.TAG_ORIENTATION, String.valueOf(ExifInterface.ORIENTATION_ROTATE_270));
break;
case 8:
exif.setAttribute(ExifInterface.TAG_ORIENTATION, String.valueOf(ExifInterface.ORIENTATION_NORMAL));
break;
}
exif.saveAttributes();
} catch (Exception e) {
e.printStackTrace();
}
}
Another solution works with Bitmap but without animation, quality can decrease and rotate can be not smoothly, test it.
ImageView photoView = findViewById(R.id.photo_view);
ImageView rotate_image = findViewById(R.id.rotate_image);
final Bitmap[] bitmap = {BitmapFactory.decodeFile(file.getPath())};
//If you dont use file add this code inside of setOnClickListener
//bitmap[0] =((BitmapDrawable) photoView.getDrawable()).getBitmap();
rotate_image.setOnClickListener(view -> {
//bitmap[0] =((BitmapDrawable) photoView.getDrawable()).getBitmap();
Matrix matrix = new Matrix();
matrix.postRotate(90);
bitmap[0] = Bitmap.createBitmap(bitmap[0], 0, 0, bitmap[0].getWidth(), bitmap[0].getHeight(), matrix, true);
photoView.setImageBitmap(bitmap[0]);
});
I added link address above and it is example code:
ImageView photoView = findViewById(R.id.photo_view);
ImageView rotate_image = findViewById(R.id.rotate_image);
rotate_image.setOnClickListener(view -> {
float scale = photoView.getRotation() % 180 == 0 ? (float) photoView.getWidth() / photoView.getHeight() : 1.0f;
photoView.animate().rotationBy(90).scaleX(scale).scaleY(scale).setDuration(100).start();
});