В этом уроке:

- используем clip

 

Обычно нам для рисования доступна вся канва. Но бывают случаи, когда надо нарисовать объект так, чтобы прорисовалась только какая-то его часть, а остальное – нет.

Из жизни можно провести аналогию с двумя бумажными листами. Кладем один лист на стол. А во втором вырезаем отверстие нужной нам формы и кладем второй лист поверх на первый. Далее полностью закрашиваем второй лист краской и убираем его. В итоге получаем на первом листе нужную нам форму ровно закрашенную.

Вот что-то подобное делает clip. Он на канве определяет область, где рисование будет работать. А в остальных местах ничего рисоваться не будет.

 

Создадим проект:

Project name: P1481_CanvasClip
Build Target: Android 2.3.3
Application name: CanvasClip
Package name: ru.startandroid.develop.p1481canvasclip
Create Activity: MainActivity

 

MainActivity.java:

package ru.startandroid.develop.p1481canvasclip;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Bundle;
import android.view.View;

public class MainActivity extends Activity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(new DrawView(this));
  }

  class DrawView extends View {

    Paint p;
    Rect rect;

    public DrawView(Context context) {
      super(context);
      p = new Paint();
      p.setStyle(Paint.Style.STROKE);
      p.setStrokeWidth(3);
      rect = new Rect(210, 210, 410, 510);
    }

    @Override
    protected void onDraw(Canvas canvas) {
      canvas.drawARGB(80, 102, 204, 255);

      // сетка
      p.setColor(Color.BLUE);
      drawGrid(canvas);

      // красный прямоугольник
      p.setColor(Color.RED);
      canvas.drawRect(rect, p);
    }

    private void drawGrid(Canvas canvas) {
      for (int i = 25; i < 400; i += 25) {
        canvas.drawLine(100 + i, 100, 100 + i, 600, p);
      }
      for (int i = 25; i < 500; i += 25) {
        canvas.drawLine(100, 100 + i, 500, 100 + i, p);
      }

    }

  }

}
Просто выводим на экран сетку из линий синим цветом и прямоугольник rect красным цветом.

 

Результат:

 

Изменим пример так, чтобы красный прямоугольник ограничивал область рисования на канве.

Перепишем onDraw:

    @Override
    protected void onDraw(Canvas canvas) {
      canvas.drawARGB(80, 102, 204, 255);
      
      // сетка
      p.setColor(Color.BLUE);
      drawGrid(canvas);
      
      // красный прямоугольник
      p.setColor(Color.RED);
      canvas.drawRect(rect, p);
      
      // смещение
      canvas.translate(600, 0);
      
      // задание clip-области
      canvas.clipRect(rect);
      
      // сетка 
      p.setColor(Color.BLUE);
      drawGrid(canvas);
      
    }

Мы снова выводим синие линии и красный прямоугольник. Затем смещаемся вправо и вместо рисования красного прямоугольника мы методом clipRect говорим канве, что теперь рисование доступно только в этой области. И рисуем синие линии.

 

Результат:

Видим, что справа линии нарисовались только в области rect, т.к. мы задали это методом clipRect.

Разумеется, clip-область будет работать только для последующих рисований. Все, что было нарисовано до задания этой области, остается как было.

 

 

При задании clip-области мы можем использовать несколько прямоугольников. Для добавления прямоугольников используется эта версия метода: clipRect(Rect rect, Region.Op op). Здесь используются режимы взаимодействия областей, которые мы подробно рассмотрели в прошлом уроке про регионы.

 

Посмотрим на примере. Перепишем класс DrawView:

  class DrawView extends View {

    Paint p;
    Rect rect1;
    Rect rect2;
    Region.Op op = Region.Op.UNION;

    public DrawView(Context context) {
      super(context);
      p = new Paint();
      p.setStyle(Paint.Style.STROKE);
      p.setStrokeWidth(3);
      rect1 = new Rect(180, 220, 340, 380);
      rect2 = new Rect(280, 320, 440, 480);
    }

    @Override
    protected void onDraw(Canvas canvas) {
      canvas.drawARGB(80, 102, 204, 255);

      // сетка
      p.setColor(Color.BLUE);
      drawGrid(canvas);

      // красные прямоугольники
      p.setColor(Color.RED);
      canvas.drawRect(rect1, p);
      canvas.drawRect(rect2, p);

      // смещение
      canvas.translate(600, 0);

      // задание clip-области
      canvas.clipRect(rect1);
      canvas.clipRect(rect2, op);

      // сетка
      p.setColor(Color.BLUE);
      drawGrid(canvas);

    }

    private void drawGrid(Canvas canvas) {
      for (int i = 25; i < 400; i += 25) {
        canvas.drawLine(100 + i, 100, 100 + i, 600, p);
      }
      for (int i = 25; i < 500; i += 25) {
        canvas.drawLine(100, 100 + i, 500, 100 + i, p);
      }
    }

  }

При использовании UNION, области прямоугольников объединились в одну область и она стала clip-областью.

 

Результат:

 

 

Чтобы убрать clip-область, можно использовать метод restore. Все те механизмы сохранения/восстановления канвы, что мы рассмотрели в Уроке 146 относятся не только к матрице, но и к clip.

Я в этом уроке использовал объекты Rect. Но у канвы существуют и другие версии метода задания clip-области. Можно использовать RectF, Region и Path. 


Присоединяйтесь к нам в Telegram:

- в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.

- в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Compose, Kotlin, RxJava, Dagger, Тестирование, Performance 

- ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня




Language

Автор сайта

Дмитрий Виноградов

Подробнее можно посмотреть или почитать.

Никакие другие люди не имеют к этому сайту никакого отношения и просто занимаются плагиатом.

Социальные сети

 

В канале я публикую ссылки на интересные и полезные статьи по Android

В чате можно обсудить вопросы и проблемы, возникающие при разработке



Группа ВКонтакте



Поддержка проекта

Яндекс
410011180491924

WebMoney
R248743991365
Z551306702056

Paypal