SVG上的Android RotateDrawable产生锯齿状边缘

时间:2019-09-19 09:58:35

标签: java android svg android-vectordrawable

我正在尝试通过编程方式旋转使用 New-> Vector Asset 方法从.svg文件创建的矢量可绘制对象,从而在Android 9设备上可视化旋转对象。对象的旋转应遵循某些外部属性的更改,而不是预定义的动画。

当将矢量图像作为VectorDrawable绘制在ImageView上时,生成的图像具有应有的平滑边缘,但是当使用RotateDrawable以编程方式旋转图像时,边缘变得锯齿状,就好像该图像被视为位图,并且不会重绘为矢量图形。

下图说明了此问题:

Below is the pure Drawable, top is the rotated version with jagged edges

根据VectorDrawable文档,在首次加载矢量资源时会为其创建位图缓存,但是是否有可能在旋转图像时强制重新渲染?

下面是一些用于创建效果的示例代码。

可绘制类:

    public class MyDrawable extends Drawable implements Drawable.Callback, Runnable {

    @Override
    public void draw(Canvas canvas)
    {
        VectorDrawable vectorDrawable = (VectorDrawable)mainActivity.getResources().getDrawable(R.drawable.test_drawable, mainActivity.getTheme());
        vectorDrawable.setBounds(canvas.getClipBounds());
        vectorDrawable.draw(canvas);    // This looks OK

        RotateDrawable rotator = new RotateDrawable();
        rotator.setBounds(canvas.getClipBounds());
        rotator.setLevel(1000);
        rotator.setDrawable(vectorDrawable.mutate());
        rotator.draw(canvas);       // Jagged edges
    }
}

在片段的ImageView中使用:

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        final ImageView testView = (ImageView)getView().findViewById(R.id.test_view);
        testView.setImageDrawable(new MyDrawable());
    }

1 个答案:

答案 0 :(得分:0)

Android上目前似乎尚无内置支持,但我找到了至少一个可行的解决方案,即使用第三方AndroidSVG库并修改.svg最上面的组<g>元素直接包含一个转换:

@Override
public void draw(Canvas canvas)
{
    try {

        String svgString = // Your .svg file as plaintext
        svgString = svgString.replaceFirst("<g>", "<g transform=\"rotate(" + angle + ", " + pivotX + " , " + pivotY + ")\">");
        SVG svg = SVG.getFromString(svgString);
        svg.renderToCanvas(canvas);

        // ...
    }
    catch (SVGParseException svgpe){}

}