Android RotateDrawable на SVG создает неровные края - PullRequest
0 голосов
/ 19 сентября 2019

Я пытаюсь визуализировать вращающийся объект на устройстве Android 9, программно поворачивая векторную графику, созданную из файла .svg с использованием метода New-> Vector Asset .Вращение объекта должно следовать изменениям некоторого внешнего свойства вместо предопределенной анимации.

Когда векторное изображение рисуется в ImageView как VectorDrawable, полученное изображение имеет ровные края, как и должно быть, но когда изображение поворачивается программно с помощью RotateDrawable, края становятся неровными, как если бы изображение былорассматривается как растровое изображение, а не перерисовывается как векторная графика.

Изображение ниже иллюстрирует эту проблему:

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

Согласно документации VectorDrawable , кэш растровых изображенийсоздан для каждого векторного актива при его первой загрузке, но есть ли возможность принудительного повторного рендеринга при повороте изображения?

Ниже приведен пример кода, используемого для создания эффекта.

Класс Drawable:

    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 голосов
/ 20 сентября 2019

Кажется, в настоящее время в Android нет встроенной поддержки того, чего я пытаюсь достичь, но я нашел по крайней мере одно работающее решение, которое заключается в использовании сторонней библиотеки AndroidSVG иизмените элемент <g> самой верхней группы .svg, чтобы включить преобразование:

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

}
...