【问题标题】:Android RotateDrawable on SVG produces jagged edgesSVG 上的 Android RotateDrawable 产生锯齿状边缘
【发布时间】:2020-01-20 08:04:48
【问题描述】:

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

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

下图说明了这个问题:

根据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
    }
}

在 Fragment 中的 ImageView 中使用:

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

【问题讨论】:

  • "as if the image was treated as a bitmap" 这正是 VectorDrawable 呈现自身的方式 - 只有 AnimatedVectorDrawable 在没有额外位图的情况下绘制自己
  • 我想要实现的是根据某些外部属性的变化值动态更改VectorDrawable 的旋转。据我了解AnimatedVectorDrawable只能用于执行预定义的动画,这不是我要找的。​​span>
  • 然后使用kyrie - 它是@github
  • 为什么不用像这样的简单 xml 动画:stackoverflow.com/a/4846255/8528047 如果您要制作复杂的动画,您可以使用 lottie 并在后效中制作它们。
  • 改用 SVG 渲染库。这种用法不是 VectorDrawables 的用途。

标签: java android svg android-vectordrawable


【解决方案1】:

目前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){}

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-06
    • 1970-01-01
    • 2019-04-30
    • 2019-07-22
    • 1970-01-01
    相关资源
    最近更新 更多