Background
I know it's possible to create a rotated version of a Drawable (or Bitmap), as such (written about it here) :
@JvmStatic
fun getRotateDrawable(d: Drawable, angle: Int): Drawable {
if (angle % 360 == 0)
return d
return object : LayerDrawable(arrayOf(d)) {
override fun draw(canvas: Canvas) {
canvas.save()
canvas.rotate(angle.toFloat(), (d.bounds.width() / 2).toFloat(), (d.bounds.height() / 2).toFloat())
super.draw(canvas)
canvas.restore()
}
}
}
The problem
I wanted to have autoMirrored
being set to some drawable (VectorDrawable in my case), which would flip (mirror so that left is right, and right is left, but not affect top and bottom) it in case the locale of the device is RTL.
As an example (and it's only an example!), if you take a drawable that shows a left-arrow, after flipping it will be a right-arrow.
Sadly, this is available only from API 19.
That's why I decided to make a new Drawable out of it, to be a flipped version of the original one
What I've tried
I've found a nice article of doing the same thing to a View, here, using a Matrix. So I've tried this:
@JvmStatic
fun getMirroredDrawable(d: Drawable): Drawable {
return object : LayerDrawable(arrayOf(d)) {
override fun draw(canvas: Canvas) {
canvas.save()
val matrix = Matrix()
// use this for the other flipping: matrix.preScale(1.0f, -1.0f)
matrix.preScale(-1.0f, 1.0f);
canvas.matrix = matrix
super.draw(canvas)
canvas.restore()
}
}
}
Sadly, for some reason, this made the drawable not being shown at all. Maybe it does work, yet tries to get shown out of its bounds of whatever View that's showing it.
The question
How can I make a flipped version of a given Drawable, similar to what I did for rotating a Drawable?
Solution:
Based on the answer suggested below (here), here's a nice way to do it:
fun Drawable.getMirroredDrawable(): Drawable {
return object : LayerDrawable(arrayOf(this)) {
val drawingRect = Rect()
val matrix = Matrix()
override fun draw(canvas: Canvas) {
matrix.reset()
matrix.preScale(-1.0f, 1.0f, canvas.width / 2.0f, canvas.height / 2.0f)
canvas.matrix = matrix
drawingRect.left = (canvas.width - intrinsicWidth) / 2
drawingRect.top = (canvas.height - intrinsicHeight) / 2
drawingRect.right = drawingRect.left + intrinsicWidth
drawingRect.bottom = drawingRect.top + intrinsicHeight
if (bounds != drawingRect)
bounds = drawingRect
super.draw(canvas)
}
}
}