Android: Imageview Rotation Animation - Keep Scale Type Fit Center
Instead of
iv.animate().rotationBy(90f).start();
two more update take android:configChanges
like that
<activityandroid:name=".youactivity"android:label="@string/app_name"android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"
>
android:adjustViewBounds true to imageview
<ImageView
android:id="@+id/iv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitCenter"
android:layout_centerInParent="true"
android:adjustViewBounds="true"
android:src="@mipmap/android"/>
Solution 2:
My Solution is not elegant (i am a noob in developing) I hope someone can provide a better solution ....
int h,w;
Boolean safe=true;
Getting the parameters of imageView is not possible at initialisation of activity To do so please refer to this solutionOR set the dimensions at onClick of a Button Like this
rotateButton.setOnClickListener(newView.OnClickListener() {
@OverridepublicvoidonClick(View view) {
if(imageView.getRotation()/90%2==0){
h=imageView.getHeight();
w=imageView.getWidth();
}
.
.//Insert the code Snippet below here
}
And the code to be run when we want to rotate ImageView
if(safe)
imageView.animate().rotationBy(90).scaleX(imageView.getRotation()/90%2==0?(w*1.0f/h):1).scaleY(imageView.getRotation()/90%2==0?(w*1.0f/h):1).setDuration(2000).setInterpolator(newLinearInterpolator()).setListener(newAnimator.AnimatorListener() {
@OverridepublicvoidonAnimationStart(Animator animation) {
safe=false;
}
@OverridepublicvoidonAnimationEnd(Animator animation) {
safe=true;
}
@OverridepublicvoidonAnimationCancel(Animator animation) {
}
@OverridepublicvoidonAnimationRepeat(Animator animation) {
}
}).start();
}
});
This solution is sufficient for the Problem above.Although it will shrink the imageView even if it is not necessary(when height is smaller than Width).If it bothers you,you can add another ternary operator inside scaleX/scaleY.
Solution 3:
To do this follow these steps:
- set
scaleType
to matrix:
<ImageView...android:scaleType="matrix"/>
- In onCreate, load image into imageview and set rotate button onClick listener:
imageView.post(new Runnable() {
@Override
publicvoidrun() {
Bitmap bitmap= BitmapFactory.decodeResource(getResources(),R.drawable.dummy);
imageView.setImageBitmap(bitmap);
if (bitmap.getWidth() > 0) {
float scale = ((float)imageView.getMeasuredWidth())/((float)imageView.getDrawable().getIntrinsicWidth());
imageView.getLayoutParams().height = (int)(scale * imageView.getDrawable().getIntrinsicHeight());
imageView.setImageMatrix(scaleMatrix(scale, scale));
}
}
});
And
btnRotate.setOnClickListener(newView.OnClickListener() {
@OverridepublicvoidonClick(View view) {
animateImageHeight(imageView,btnRotate);
}
});
- Add the animateImageHeight method in the activity:
void animateImageHeight(final ImageView imageView, final Button btnRotate){
finalfloatdrawableWidth= imageView.getDrawable().getIntrinsicWidth();
finalfloatdrawableHeight= imageView.getDrawable().getIntrinsicHeight();
floatviewWidth= imageView.getMeasuredWidth();
finalfloatviewHeight= imageView.getMeasuredHeight();
finalintrotation= imageRotation % 360;
finalintnewRotation= (rotation + 90);
finalint newViewHeight;
finalfloat imageScale;
finalfloat newImageScale;
if (rotation==0 || rotation==180)
{
imageScale = viewWidth / drawableWidth;
newImageScale = viewWidth / drawableHeight;
newViewHeight = (int)(drawableWidth * newImageScale);
}
elseif (rotation==90 || rotation==270){
imageScale = viewWidth / drawableHeight;
newImageScale = viewWidth / drawableWidth;
newViewHeight = (int)(drawableHeight * newImageScale);
}
else{
thrownewUnsupportedOperationException("rotation can 0, 90, 180 or 270. ${rotation} is unsupported");
}
ValueAnimator animator= ValueAnimator.ofFloat(0f,1f) .setDuration(1000L);
animator.setInterpolator(newAccelerateDecelerateInterpolator());
animator.addListener(newAnimator.AnimatorListener() {
@OverridepublicvoidonAnimationStart(Animator animator) {
btnRotate.setEnabled(false);
}
@OverridepublicvoidonAnimationEnd(Animator animator) {
imageRotation = newRotation % 360;
btnRotate.setEnabled(true);
}
@OverridepublicvoidonAnimationCancel(Animator animator) {
}
@OverridepublicvoidonAnimationRepeat(Animator animator) {
}
});
animator.addUpdateListener(newValueAnimator.AnimatorUpdateListener() {
@OverridepublicvoidonAnimationUpdate(ValueAnimator animation) {
floatanimVal= (float)animation.getAnimatedValue();
floatcomplementaryAnimVal=1 - animVal;
intanimatedHeight=
(int)(complementaryAnimVal * viewHeight + animVal * newViewHeight);
floatanimatedScale=
(complementaryAnimVal * imageScale + animVal * newImageScale);
floatanimatedRotation=
(complementaryAnimVal * rotation + animVal * newRotation);
imageView.getLayoutParams().height=animatedHeight;
Matrix matrix=
rotationMatrix(
animatedRotation,
drawableWidth / 2,
drawableHeight / 2
);
matrix.postScale(
animatedScale,
animatedScale,
drawableWidth / 2,
drawableHeight / 2);
matrix.postTranslate(-(drawableWidth - imageView.getMeasuredWidth())/2, -(drawableHeight - imageView.getMeasuredHeight())/2);
imageView.setImageMatrix(matrix);
imageView.requestLayout();
}
});
animator.start();
}
You can find the kotlin version and the complete demonstration here.
Solution 4:
try:
<?xml version="1.0" encoding="utf-8"?><layout><androidx.constraintlayout.widget.ConstraintLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><ImageViewandroid:id="@+id/image"android:layout_width="match_parent"android:layout_height="match_parent"android:src="@drawable/pic"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent" /></androidx.constraintlayout.widget.ConstraintLayout></layout>
privatelateinitvar binding: ActivityMainBinding
privatevar scale = 1FoverridefunonCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
//Change to your own calculation logic to calculate the zoom factorval outMetrics = DisplayMetrics()
windowManager.getDefaultDisplay().getRealMetrics(outMetrics)
val w = outMetrics.widthPixels
val h = outMetrics.heightPixels
scale = if (w > h) w.toFloat() / h.toFloat() else h.toFloat() / w.toFloat()
binding.image.scaleX = scale
binding.image.scaleY = scale
}
funset() {
sfRotation = (sfRotation + 90) % 360
Log.d(">>>sfRotation", sfRotation.toString())
Log.d(">>>hwrotation", hwRotation.toString())
binding.image.rotation = sfRotation.toFloat()
binding.image.scaleX = scale
binding.image.scaleY = scale
}
Post a Comment for "Android: Imageview Rotation Animation - Keep Scale Type Fit Center"