You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建指定Drawable的镜像版本?适配Android低API版本

实现Drawable的水平镜像翻转(适配API 19以下)

我明白你的需求:要给VectorDrawable实现类似autoMirrored的效果,在RTL语言环境下完成水平翻转(左右互换、不影响上下),但这个系统属性仅在API 19及以上可用,所以需要手动实现镜像版本,还要贴合你之前旋转Drawable的实现思路。

为什么你之前的尝试会失效?

你之前用Matrix做水平缩放的代码,问题出在只做了画布翻转,却没调整Drawable的绘制边界——翻转后Drawable的绘制位置直接超出了承载View的可视区域,所以看起来像是完全不显示了。

可行的实现方案

结合你之前旋转Drawable的思路,我们可以通过LayerDrawable包装原Drawable,在绘制时同步调整画布矩阵和Drawable的绘制边界,确保它能正确显示在View内部:

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

            // 计算Drawable在画布中的居中绘制区域
            drawingRect.left = (canvas.width - intrinsicWidth) / 2
            drawingRect.top = (canvas.height - intrinsicHeight) / 2
            drawingRect.right = drawingRect.left + intrinsicWidth
            drawingRect.bottom = drawingRect.top + intrinsicHeight

            // 更新Drawable的bounds到计算好的区域,避免绘制偏移
            if (bounds != drawingRect) bounds = drawingRect

            super.draw(canvas)
        }
    }
}

关键细节解释

  • Matrix翻转逻辑:matrix.preScale(-1.0f, 1.0f, canvas.width / 2.0f, canvas.height / 2.0f) 是核心,它以画布中心为基准点进行水平翻转,避免Drawable整体偏移出画布范围。
  • 调整Drawable Bounds:通过计算居中的drawingRect,把Drawable的绘制边界锁定在这个区域,确保翻转后的内容能完整显示在View的可视范围内。
  • 复用LayerDrawable:和你之前旋转Drawable的实现方式一致,用LayerDrawable包装原Drawable,不需要额外创建Bitmap,既能保留VectorDrawable的矢量特性,也能保证性能。

使用方式

直接在需要镜像的Drawable上调用这个扩展函数即可:

val originalDrawable = ContextCompat.getDrawable(context, R.drawable.ic_left_arrow)
val mirroredDrawable = originalDrawable?.getMirroredDrawable()

内容的提问来源于stack exchange,提问作者android developer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:20:34