Что является лучшей альтернативой для canvas.clipRect с помощью Region.Op.REPLACE? - PullRequest
0 голосов
/ 08 мая 2018

Фон

Я работаю над библиотекой, в которой много рисунков на холсте вместо нескольких видов (доступно здесь ).

Проблема

Когда я работаю над его улучшением и тем, чтобы оно работало для наших нужд приложения (требуется некоторая настройка), я заметил, что есть строки, помеченные как устаревшие:

canvas.clipRect(0f, mHeaderHeight + mHeaderRowPadding * 2, mHeaderColumnWidth, height.toFloat(), Region.Op.REPLACE)

Дело в том, что я не думаю, что есть хороший кандидат для замены этой строки кода более новыми API

Что я нашел

Глядя на документы , вот что написано:

Этот метод устарел на уровне API 26. Значения Region.Op другое чем INTERSECT и DIFFERENCE имеют возможность расширить клип. API обрезки холста предназначены только для расширения клипа в результате операции восстановления. Это позволяет родителю представления обрезать холст четко определить максимальную область рисования своих детей. Рекомендуемые альтернативные вызовы: clipRect (RectF) и clipOutRect (RectF); * 1 025 *

Итак, я попытался использовать любую из этих функций, но обе они вызвали проблемы с изображением, как раньше.

Глядя на устаревание, кажется, что сама функция помечена, но не Region.Op.REPLACE:

enter image description here

Так что, может быть, у него нет альтернативы ...

Вопросы

  1. Какая лучшая альтернатива в этом случае?
  2. Почему именно это устарело?
  3. В отличие от некоторых устаревших функций, я полагаю, что эта функция должна быть безопасной для дальнейшего использования в случае, если я не могу найти альтернативу, верно?

1 Ответ

0 голосов
/ 09 мая 2018

1: Все методы, использующие пользовательские Region.Op, устарели, поэтому сейчас можно использовать только два варианта методов: clipRect / clipPath (что представляет Region.Op.INTERSECT) и clipOutRect / clipOutPath ( что представляет Region.Op.DIFFERENCE). Для достижения функции, аналогичной Region.Op.REPLACE, необходимо использовать методы save() и restore().

Итак, ранее (с Op.REPLACE) вы бы назвали просто:

canvas.clipRect(0, 0, 100, 100); // do some clipping
canvas.drawLine(...); // do some clipped drawing

canvas.clipRect(200, 200, 400, 400, Region.Op.REPLACE); // replace clipping region to completely different one
canvas.drawLine(...); // and some other drawing

Но теперь вам нужно сохранить и восстановить предыдущее состояние холста вручную:

canvas.save();        // IMPORTANT: save current state of clip and matrix (i.e. unclipped state) (let's say it's state #1)
canvas.clipRect(0, 0, 100, 100); // do some clipping
canvas.drawLine(...); // do some clipped drawing
canvas.restore();     // IMPORTANT: get back to previously saved (unclipped) state of the canvas (restores state #1)

canvas.save(); // now save again the current state of canvas (clip and matrix) (it's state #2)
canvas.clipRect(200, 200, 400, 400); // now we can do some other clipping (as we would do with Region.Op.REPLACE before)
canvas.drawLine(...); // and some other drawing
canvas.restore(); // get back go previously saved state (to state #2)

Примечание. Canvas внутренне использует стек, поэтому вы даже можете вызывать save() несколько раз в разные моменты. Вы просто не можете звонить canvas.restore() больше раз, чем canvas.save() звонили.

Также важно отметить, что вызов canvas.restore() изменяет прямоугольник клипа (на то же значение, которое было при вызове canvas.save()). Поэтому вы должны аккуратно выполнить вызов restore() после всех методов рисования, для которых требуется примененное ограничение.

2: Возможно, из-за некоторых оптимизаций производительности. Я думаю, что где-то читал (я не смог найти его сейчас), что для аппаратного ускорения на GPU они могут использовать только операции клипа INTERSECT / DIFFERENCE, а другие должны отступать от обработки процессора. Это может быть причиной.

EDIT: Здесь - это некоторый связанный ответ, что, поскольку ICS с включенным ускорением HW, некоторые операции ClipRect не поддерживаются.

3: Как говорится в документации, он перестанет работать в Android P (возможно, только при таргетинге на Android P):

Начиная с уровня API Уровень API Build.VERSION_CODES.P только INTERSECT и DIFFERENCE являются допустимыми параметрами Region.Op.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...