Android SDK: создание приложения для рисования - сенсорное взаимодействие
Russian (Pусский) translation by Elen (you can also view the original English article)
В серии нескольких статье мы создадим приложение для рисования с помощью пальцев для Android, использующее сенсорное взаимодействие. У пользователя будет возможность выбирать цвет из цветовой палитры, размер кисти, стирать, создавать новый рисунок или сохранять уже существующий в галерее устройства.
Формат урока
Данный урок по созданию приложения для рисования будет состоять из трех частей:
Просмотр конечного результата



В первой части серии нескольких уроков мы создадим пользовательский интерфейс. Во второй части мы осуществим рисование на холсте и выбор цветов. В заключительной части мы представим возможность стирать, создавать новые рисунки и сохранять их в галерее пользовательского устройства. Мы рассмотрим опции, которые вы сможете использовать для улучшения этого приложения, проходя в будущем другие учебные материалы, включая заливку холста, прозрачность и другое взаимодействие, отличное от сенсорного.
1. Подготовка к рисованию
Шаг 1
В прошлый раз мы создали класс с именем «DrawingView», который представляет собой пользовательский View для функций рисования, которые должны выполняться внутри. Мы создали схему объявления класса и метод с именем «setupDrawing» - вот сейчас мы сделаем это. В своем классе DrawingView
добавьте следующие операторы импорта:
import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Path; import android.view.MotionEvent;
Затем добавьте некоторые переменные экземпляра в верхней части класса:
//drawing path private Path drawPath; //drawing and canvas paint private Paint drawPaint, canvasPaint; //initial color private int paintColor = 0xFF660000; //canvas private Canvas drawCanvas; //canvas bitmap private Bitmap canvasBitmap;
Когда пользователь прикасается к экрану и перемещает палец, чтоб рисовать, мы будем использовать Path для отслеживания его действий рисования на холсте. Как холст, так и рисунок поверх него представлены объектами Paint. Начальный цвет краски соответствует первому цвету в палитре, которую мы создали в последний раз, и которая будет первоначально выбрана при запуске приложения. Наконец, мы объявляем переменные для холста и растрового изображения: пути пользователя, нарисованные с помощью drawPaint
, будут нарисованы на холсте, который нарисован canvasPaint
.
Шаг 2
Давайте создадим в методе setupDrawing
некоторые из этих переменных, чтобы установить класс для рисования. Сначала создайте объекты рисования Path и Paint:
drawPath = new Path(); drawPaint = new Paint();
Затем установите начальный цвет:
drawPaint.setColor(paintColor);
Теперь задайте начальные свойства пути:
drawPaint.setAntiAlias(true); drawPaint.setStrokeWidth(20); drawPaint.setStyle(Paint.Style.STROKE); drawPaint.setStrokeJoin(Paint.Join.ROUND); drawPaint.setStrokeCap(Paint.Cap.ROUND);
Мы изменим часть этого кода в следующем уроке, когда реализуем возможность выбора размеров кистей; пока мы установим произвольный размер кисти. Настройка сглаживания, штрихов и стилей сделает рисунки пользователя более гладкими.
Завершите метод setupDrawing
, создав экземпляр объекта Paint:
canvasPaint = new Paint(Paint.DITHER_FLAG);
На этот раз мы устанавливаем сглаживание, передавая параметр конструктору.
Шаг 3
Нам нужно переопределить несколько методов, чтобы сделать пользовательскую функцию View в виде чертежа. Во-первых, все еще находясь внутри класса DrawingView
, переопределите метод onSizeChanged
, который будет вызываться, когда пользовательскому View присваивается размер:
@Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { //view given size }
Внутри этого метода вызовите сначала метод суперкласса:
super.onSizeChanged(w, h, oldw, oldh);
Теперь создайте холст для рисования и растрового изображения, используя значения ширины и высоты:
canvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); drawCanvas = new Canvas(canvasBitmap);
Шаг 4
Чтобы позволить классу функционировать как View чертежа пользователя, нам также необходимо переопределить метод onDraw
, поэтому сейчас добавьте его в класс:
@Override protected void onDraw(Canvas canvas) { //draw view }
Внутри метода нарисуйте холст и путь рисования:
canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint); canvas.drawPath(drawPath, drawPaint);
Пока мы еще не реализовали возможность для пользователя рисовать путь с помощью Paint, но как только мы это сделаем, он будет представлен в View. Каждый раз, когда пользователь рисует с помощью сенсорного взаимодействия, мы аннулируем View, заставляя выполняться метод onDraw
.
2. Содействие рисованию
Шаг 1
Когда чертеж View находится на экране приложения, мы хотим, чтобы пользователь касался его для регистрации в качестве операций рисования. Для этого нам нужно проследить сенсорные события. В своем классе drawingView
добавьте следующий метод:
@Override public boolean onTouchEvent(MotionEvent event) { //detect user touch }
Внутри метода извлеките X и Y позиции касания пользователя:
float touchX = event.getX(); float touchY = event.getY();
Шаг 2
Параметр MotionEvent
в onTouchEvent
методе позволит нам реагировать на определенные события прикосновения. Действия, в которых мы заинтересованы, чтобы применить рисование, - down
, move
и up
. Добавьте оператор switch в метод для ответа на каждый из следующих:
switch (event.getAction()) { case MotionEvent.ACTION_DOWN: drawPath.moveTo(touchX, touchY); break; case MotionEvent.ACTION_MOVE: drawPath.lineTo(touchX, touchY); break; case MotionEvent.ACTION_UP: drawCanvas.drawPath(drawPath, drawPaint); drawPath.reset(); break; default: return false; }
Найдите минутку, чтобы просмотреть этот код. Когда пользователь касается View, мы перемещаемся в это положение, чтобы начать рисовать. Когда он двигает пальцем по View, мы рисуем путь вместе с его прикосновением. Когда он забирает свой палец от View, мы рисуем Path, и перезагружаем его для следующей операции рисования.
Шаг 3
После оператора switch завершите метод, сделав недействительным View и вернув истинное значение:
invalidate(); return true;
Вызов invalidate
вызовет выполнение метода onDraw
.
3. Выбор цветов
Шаг 1
Теперь давайте реализуем возможность пользователя выбирать цвета из палитры. В главном Activity приложения добавьте следующие импорты:
import android.view.View; import android.widget.ImageButton; import android.widget.LinearLayout;
Добавьте в класс следующую переменную экземпляра:
private DrawingView drawView;
Это представляет экземпляр пользовательского View, который мы добавили в макет. Внутри onCreate
, после существующего кода, создайте эту переменную, извлекая ссылку на нее из макета:
drawView = (DrawingView)findViewById(R.id.drawing);
Теперь у нас есть View, который отображается в Activity, на котором мы можем вызвать методы в классе DrawingView
.
Шаг 2
Мы устанавливаем исходный цвет в классе чертежа View, давайте теперь настроим пользовательский интерфейс, чтобы отображать и управлять им. В основном классе Activity добавьте другую переменную экземпляра, чтобы отобразить кнопку цвета на палитре:
private ImageButton currPaint;
Внутри onCreate
мы теперь хотим получить первую кнопку цвета краски в области палитры, которая изначально будет выбрана. Сначала найдите Linear Layout, содержащуюся внутри:
LinearLayout paintLayout = (LinearLayout)findViewById(R.id.paint_colors);
Получите первую кнопку и сохраните ее как переменную экземпляра:
currPaint = (ImageButton)paintLayout.getChildAt(0);
На кнопке мы будем использовать другое изображение, которое можно нарисовать, чтобы показать, что оно выбрано в настоящий момент:
currPaint.setImageDrawable(getResources().getDrawable(R.drawable.paint_pressed));
Добавьте этот файл в чертежи вашего приложения, указав ему имя "paint_pressed.xml" и введя следующую форму:
<layer-list xmlns:android="https://schemas.android.com/apk/res/android" > <item> <shape android:shape="rectangle" > <stroke android:width="4dp" android:color="#FF333333" /> <solid android:color="#00000000" /> <padding android:bottom="0dp" android:left="0dp" android:right="0dp" android:top="0dp" /> </shape> </item> <item> <shape xmlns:android="http://schemas.android.com/apk/res/android" > <stroke android:width="4dp" android:color="#FF333333" /> <solid android:color="#00000000" /> <corners android:radius="10dp" /> </shape> </item> </layer-list>
Это очень похоже на «paint.xml», который мы создали в последний раз, но с темным цветом вокруг краски.
Шаг 3
Теперь мы можем позволить пользователю выбирать цвета. Когда в последний раз мы создавали макет, мы указали атрибут onClick
для кнопок цветовой палитры; теперь добавьте метод в свой основной класс Activity:
public void paintClicked(View view){ //use chosen color }
Внутри этого метода сначала убедитесь, что пользователь щелкнул цвет краски, который не выбран в данный момент:
if(view!=currPaint){ //update color }
Внутри блока if
найдите тег, который мы установили для каждой кнопки в макете, представляя выбранный цвет:
ImageButton imgView = (ImageButton)view; String color = view.getTag().toString();
Для установки цвета нам нужно использовать собственный класс View. Перейдите в класс DrawingView
и добавьте следующий метод:
public void setColor(String newColor){ //set color }
Внутри метода начните с аннулирования View:
invalidate();
Затем выполните анализ и установите цвет для рисования:
paintColor = Color.parseColor(newColor); drawPaint.setColor(paintColor);
Вернемся к нашему основному Activity и в методе paintClicked
, после получения тега цвета, вызовите новый метод на пользовательский чертежный объект View:
drawView.setColor(color);
Теперь обновите пользовательский интерфейс, чтобы отобразить новую выбранную краску, и установите предыдущую версию в обычном режиме:
imgView.setImageDrawable(getResources().getDrawable(R.drawable.paint_pressed)); currPaint.setImageDrawable(getResources().getDrawable(R.drawable.paint)); currPaint=(ImageButton)view;
Вывод
Теперь вы можете запустить приложение и рисовать на холсте, выбрав цвета для рисования. Вы видите, что кнопки цветовой палитры соответствуют выбранному цвету в данный момент. В этом уроке мы проработали основные функции любого приложения для рисования под Android, поэтому теперь у вас должны быть основные навыки для реализации собственных функций рисования в других приложениях. В заключительной части серии этих уроков мы реализуем стирание, выбор размера кисти и ластика, сохранение рисунков и начало рисования новых.