Created
July 14, 2017 12:47
-
-
Save rudchenkos/e33dc0d6669a61dde9d6548f6c3e0e7e to your computer and use it in GitHub Desktop.
Maintain aspect ratio of bitmap drawables set as windowBackground on Android
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.graphics.Canvas; | |
import android.graphics.ColorFilter; | |
import android.graphics.Matrix; | |
import android.graphics.Rect; | |
import android.graphics.RectF; | |
import android.graphics.drawable.Drawable; | |
import android.support.annotation.IntRange; | |
import android.support.annotation.NonNull; | |
import android.support.annotation.Nullable; | |
/** | |
* Drawable decorator which draws the target drawable similarly to an ImageView with scaleType=centerCrop | |
* | |
* Example usage: | |
* final Drawable bg = getResources().getDrawable(R.drawable.screen); | |
* getWindow().setBackgroundDrawable(new CenterCropDrawable(bg)); | |
*/ | |
public class CenterCropDrawable extends Drawable { | |
@NonNull | |
private final Drawable target; | |
public CenterCropDrawable(@NonNull Drawable target) { | |
this.target = target; | |
} | |
@Override | |
public void setBounds(@NonNull Rect bounds) { | |
super.setBounds(bounds.left, bounds.top, bounds.right, bounds.bottom); | |
} | |
@Override | |
public void setBounds(int left, int top, int right, int bottom) { | |
final RectF sourceRect = new RectF(0, 0, target.getIntrinsicWidth(), target.getIntrinsicHeight()); | |
final RectF screenRect = new RectF(left, top, right, bottom); | |
final Matrix matrix = new Matrix(); | |
matrix.setRectToRect(screenRect, sourceRect, Matrix.ScaleToFit.CENTER); | |
final Matrix inverse = new Matrix(); | |
matrix.invert(inverse); | |
inverse.mapRect(sourceRect); | |
target.setBounds(Math.round(sourceRect.left), Math.round(sourceRect.top), | |
Math.round(sourceRect.right), Math.round(sourceRect.bottom)); | |
super.setBounds(left, top, right, bottom); | |
} | |
@Override | |
public void draw(@NonNull Canvas canvas) { | |
canvas.save(Canvas.CLIP_SAVE_FLAG); | |
canvas.clipRect(getBounds()); | |
target.draw(canvas); | |
canvas.restore(); | |
} | |
@Override | |
public void setAlpha(@IntRange(from = 0, to = 255) int alpha) { | |
target.setAlpha(alpha); | |
} | |
@Override | |
public void setColorFilter(@Nullable ColorFilter colorFilter) { | |
target.setColorFilter(colorFilter); | |
} | |
@Override | |
public int getOpacity() { | |
return target.getOpacity(); | |
} | |
} |
Hi @pchell
What is your animation? Could it be that CenterCropDrawable
overrides every frame of your animanation by, well, centering the drawable?
Hi @rudchenkos !
I use animated-vector. I created a question on https://stackoverflow.com/questions/62166507/setanimatedvectordrawable-start-does-not-work-on-some-devices. I would be very grateful if you could help resolve the issue)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi) Great solution, but on some devices does enamation freeze? What could be the problem ?
Here in this version, it freeze on some devices:
animationBackground = (AnimatedVectorDrawable) getDrawable(R.drawable.splash_screen_anim); getWindow().setBackgroundDrawable(new CenterCropDrawable(animationBackground));
But, if you changed the code and remove new CenterCropDrawable, then the animation stops freezing on these devices:
animationBackground = (AnimatedVectorDrawable) getDrawable(R.drawable.splash_screen_anim); getWindow().setBackgroundDrawable(animationBackground);