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.