如何获得作为不同Drawable的镜像版本的Drawable? [英] How to get a Drawable that's a mirrored version of a different Drawable?

查看:269
本文介绍了如何获得作为不同Drawable的镜像版本的Drawable?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道可以创建Drawable(或位图)的旋转版本,就像这样(写在 此处) ):

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()
        }
    }
}

问题

我想将autoMirrored设置为某些drawable(在我的情况下为VectorDrawable),它将翻转(镜像,以便左侧为右,右侧为左,但不影响顶部和底部),以防语言环境该设备的设备是RTL.

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.

遗憾的是,仅API 19提供此功能.

Sadly, this is available only from API 19.

这就是为什么我决定用它制作一个新的Drawable,使其成为原始版本的翻页版本

That's why I decided to make a new Drawable out of it, to be a flipped version of the original one

我找到了一篇很好的文章,对View执行相同的操作,

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()
            }
        }
    }

不幸的是,由于某种原因,这使得可绘制对象完全无法显示.也许它确实有用,但它试图使其不受显示它的任何View的限制.

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.

如何制作给定Drawable的翻转版本,类似于旋转Drawable所做的事情?

How can I make a flipped version of a given Drawable, similar to what I did for rotating a Drawable?

解决方案:

根据以下建议的答案( 此处 ),这是一种不错的方法它:

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)
        }
    }
}

推荐答案

指定翻转操作的中心.

Specify the center for the flip operation.

matrix.preScale(-1.0f, 1.0f, canvas.getWidth() / 2, canvas.getHeight() / 2);

这是一个自定义的Drawable类,可用于镜像可绘制对象:

Here is a custom Drawable class that you can use to mirror drawables:

public class MirroredDrawable extends Drawable {
    final Drawable mDrawable;
    final Matrix matrix = new Matrix();

    MirroredDrawable(Drawable drawable) {
        mDrawable = drawable;
    }

    @Override
    public void draw(@NonNull Canvas canvas) {
        matrix.reset();
        matrix.preScale(-1.0f, 1.0f, canvas.getWidth() / 2, canvas.getHeight() / 2);
        canvas.setMatrix(matrix);

        Rect drawingRect = new Rect();
        drawingRect.left = (canvas.getWidth() - mDrawable.getIntrinsicWidth()) / 2;
        drawingRect.top = (canvas.getHeight() - mDrawable.getIntrinsicHeight()) / 2;
        drawingRect.right = drawingRect.left + mDrawable.getIntrinsicWidth();
        drawingRect.bottom = drawingRect.top + mDrawable.getIntrinsicHeight();
        mDrawable.setBounds(drawingRect);
        mDrawable.draw(canvas);
    }

    // Other methods required to extend Drawable but aren't used here.

    @Override
    public void setAlpha(int alpha) { }

    @Override
    public void setColorFilter(@Nullable ColorFilter colorFilter) { }

    @Override
    public int getOpacity() { return PixelFormat.OPAQUE; }
}

这里是如何应用它:

    Drawable drawable = getResources().getDrawable(R.drawable.your_drawable);
    getSupportActionBar().setHomeAsUpIndicator(new MirroredDrawable(drawable));

这篇关于如何获得作为不同Drawable的镜像版本的Drawable?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆