В этой серии мы создадим приложение для рисования пальцев для Android с помощью сенсорного взаимодействия. Пользователь сможет выбрать из цветовой палитры, выбрать размер кисти, стереть, создать новый чертеж или сохранить существующий чертеж в галерее устройства.
В этой первой части серии мы получим настройку пользовательского интерфейса приложения, затем во второй части мы реализуем функциональность рисования. В заключительной части мы добавим возможность пользователю стирать, запускать новый рисунок, сохранять существующие рисунки и выбирать размеры кисти и ластика.
Формат серии
Эта серия статей о создании приложения для рисования будет состоять из трех частей:
Финальный просмотр
Выше скриншот из приложения, из этой серии вы узнаете, как строить. Надеюсь, ваши рисунки будут лучше моих!
1. Создайте проект Android
Шаг 1
Запустите новый проект Android в Eclipse, выбрав имена приложений и пакетов. Мы используем минимальный уровень API 14 и цель 17 для кода в этом руководстве.
Позвольте Eclipse создать пустой основной Activity и макет — вы можете использовать имена по умолчанию.
Шаг 2
Откройте файл манифеста проекта и перейдите на вкладку редактирования XML. Ваши уровни активности и SDK уже должны быть установлены. Добавьте следующее к открывающему тегу элемента Activity, заставляя приложение использовать только портрет:
1
|
android:screenOrientation=»portrait»
|
Шаг 3
Прежде чем мы начнем создавать интерфейс, давайте определим некоторые числа, которые мы будем использовать на протяжении всей серии. В папке «res / values» вашего приложения, если Eclipse еще не создал его, добавьте файл «dimensions.xml» — если он уже существует, вы можете просто добавить в него новые значения. План должен быть следующим:
1
2
|
<resources>
</resources>
|
Если Eclipse создал файл, возможно, в нем уже есть некоторые значения. Мы собираемся использовать три возможных размера кисти / ластика: маленький, средний и большой. Нам необходимо определить размер для каждого из них как измерение, так и целочисленное значение, чтобы мы могли использовать эти измерения как в макете XML, так и в рисуемых ресурсах и коде Java:
1
2
3
4
5
6
7
|
<!— Brush sizes —>
<dimen name=»small_brush»>10dp</dimen>
<integer name=»small_size»>10</integer>
<dimen name=»medium_brush»>20dp</dimen>
<integer name=»medium_size»>20</integer>
<dimen name=»large_brush»>30dp</dimen>
<integer name=»large_size»>30</integer>
|
Значения для измерения и целочисленного значения для каждого размера одинаковы, поэтому пользовательский интерфейс указывает размер кисти, поскольку он будет функционировать, когда пользователь рисует с ним.
2. Создайте пользовательский класс просмотра
Шаг 1
Мы собираемся определить пользовательский класс View, в котором будет происходить рисование. В исходном пакете вашего приложения создайте новый класс. Назовите его «DrawingView» и выберите «android.view.View» в качестве суперкласса. Новый класс должен иметь следующую схему:
1
2
3
4
|
public class DrawingView extends View
{
}
|
Шаг 2
В вашем новом классе View вам потребуются следующие операторы импорта в дополнение к импорту View, который Eclipse должен был добавить для вас:
1
2
|
import android.content.Context;
import android.util.AttributeSet;
|
Добавьте метод конструктора к классу:
1
2
3
4
|
public DrawingView(Context context, AttributeSet attrs){
super(context, attrs);
setupDrawing();
}
|
Мы добавим экземпляр пользовательского представления в файл макета XML. Добавьте указанный вспомогательный метод в класс:
1
2
3
|
private void setupDrawing(){
//get drawing area setup for interaction
}
|
Мы реализуем этот метод в следующей части серии, а также добавим другие методы в класс.
3. Разработка макета деятельности
Шаг 1
Откройте XML-файл строк res / values вашего приложения и добавьте несколько текстовых строк, которые мы будем использовать в макете:
1
2
3
4
5
|
<string name=»start_new»>New</string>
<string name=»brush»>Brush</string>
<string name=»erase»>Erase</string>
<string name=»save»>Save</string>
<string name=»paint»>Paint</string>
|
Откройте основной файл макета приложения и перейдите на вкладку XML для редактирования кода. Содержимое экрана «Активность» будет проще всего реализовать с помощью линейных макетов. Замените содержимое файла макета следующим текстом:
1
2
3
4
5
6
7
8
9
|
<LinearLayout xmlns:android=»http://schemas.android.com/apk/res/android»
xmlns:tools=»http://schemas.android.com/tools»
android:layout_width=»match_parent»
android:layout_height=»match_parent»
android:background=»#FFCCCCCC»
android:orientation=»vertical»
tools:context=».MainActivity» >
</LinearLayout>
|
Мы устанавливаем вертикальную ориентацию и серый цвет фона.
Шаг 2
Внутри основного линейного макета добавьте еще один, чтобы удерживать кнопки пользовательского интерфейса в верхней части экрана:
1
2
3
4
5
6
|
<LinearLayout
android:layout_width=»wrap_content»
android:layout_height=»50dp»
android:layout_gravity=»center»
android:orientation=»horizontal» >
</LinearLayout>
|
На этот раз макет горизонтальный с установленной высотой и центрированием. Внутри этого макета мы добавим кнопки для запуска нового чертежа, выбора кисти, выбора ластика и сохранения чертежа. Мы используем следующие изображения для этих кнопок, хотя вы можете создать свои собственные, если хотите:
Скопируйте изображения в папку (и) для рисования вашего приложения — если вы создаете свое собственное, вы можете ориентироваться на определенные плотности Чтобы завершить серию уроков, не ориентируясь на конкретную плотность экрана, вы можете просто создать папку с именем «drawable» и добавить в нее все свои ресурсы для рисования.
Давайте теперь добавим ImageButton для каждой опции в Activity. Начните с кнопки, чтобы создать новый рисунок внутри второго линейного макета:
1
2
3
4
5
6
|
<ImageButton
android:id=»@+id/new_btn»
android:layout_width=»wrap_content»
android:layout_height=»fill_parent»
android:contentDescription=»@string/start_new»
android:src=»@drawable/new_pic» />
|
Мы будем использовать идентификатор для ответа на нажатия кнопок в классе «Активность». Мы указываем новое изображение значка кнопки в качестве источника для ImageButton и добавляем строку описания содержимого.
Затем добавьте кнопку кисти:
1
2
3
4
5
6
|
<ImageButton
android:id=»@+id/draw_btn»
android:layout_width=»wrap_content»
android:layout_height=»fill_parent»
android:contentDescription=»@string/brush»
android:src=»@drawable/brush» />
|
Теперь добавьте кнопку ластика:
1
2
3
4
5
6
|
<ImageButton
android:id=»@+id/erase_btn»
android:layout_width=»wrap_content»
android:layout_height=»fill_parent»
android:contentDescription=»@string/erase»
android:src=»@drawable/eraser» />
|
При нажатии на кнопку кисти или ластика пользователю будет предложено выбрать размер — мы реализуем это позже. Затем добавьте кнопку сохранения:
1
2
3
4
5
6
|
<ImageButton
android:id=»@+id/save_btn»
android:layout_width=»wrap_content»
android:layout_height=»fill_parent»
android:contentDescription=»@string/save»
android:src=»@drawable/save» />
|
Вот и все для верхних кнопок управления Linear Layout.
Шаг 3
После верхней кнопки Linear Layout, но все еще внутри внешнего Linear Layout в файле, давайте теперь добавим экземпляр созданного нами пользовательского класса представления:
01
02
03
04
05
06
07
08
09
10
|
<com.example.drawingfun.DrawingView
android:id=»@+id/drawing»
android:layout_width=»fill_parent»
android:layout_height=»0dp»
android:layout_marginBottom=»3dp»
android:layout_marginLeft=»5dp»
android:layout_marginRight=»5dp»
android:layout_marginTop=»3dp»
android:layout_weight=»1″
android:background=»#FFFFFFFF» />
|
Как видите, вы можете добавить пользовательский вид к своим макетам почти так же, как и стандартные элементы пользовательского интерфейса Android. Мы устанавливаем общие свойства макета, белый фон для рисования и предоставляем идентификатор для ссылки на представление в Java. Получив ссылку на этот экземпляр пользовательского класса View, наша Activity сможет получить доступ к методам, которые мы определили в объявлении класса View, которое мы создали.
Шаг 4
Теперь давайте добавим цветовую палитру. После пользовательского элемента View добавьте еще один линейный макет для кнопок палитры:
1
2
3
4
5
6
|
<LinearLayout
android:layout_width=»wrap_content»
android:layout_height=»wrap_content»
android:layout_gravity=»center»
android:orientation=»vertical» >
</LinearLayout>
|
Этот элемент будет содержать две строки кнопок, поэтому введите для них еще две линейные схемы. Поместите следующее в тот, который вы только что добавили:
01
02
03
04
05
06
07
08
09
10
11
12
13
|
<!— Top Row —>
<LinearLayout
android:id=»@+id/paint_colors»
android:layout_width=»wrap_content»
android:layout_height=»wrap_content»
android:orientation=»horizontal» >
</LinearLayout>
<!— Bottom Row —>
<LinearLayout
android:layout_width=»wrap_content»
android:layout_height=»wrap_content»
android:orientation=»horizontal» >
</LinearLayout>
|
Первая строка имеет идентификатор, потому что мы собираемся использовать его в Java, когда приложение начнет устанавливать первый цвет по умолчанию, выбранный так, чтобы пользователь мог сразу начать рисовать. Для каждого цвета мы будем использовать следующую структуру ImageButton :
1
2
3
4
5
6
7
8
9
|
<ImageButton
android:layout_width=»@dimen/large_brush»
android:layout_height=»@dimen/large_brush»
android:layout_margin=»2dp»
android:background=»#FF660000″
android:contentDescription=»@string/paint»
android:onClick=»paintClicked»
android:src=»@drawable/paint»
android:tag=»#FF660000″ />
|
Пока не добавляйте это в свой файл макета — мы сделаем это в ближайшее время, а пока посмотрим на код. Мы используем одно из значений измерения, которое мы определили для цветной кнопки. Обратите внимание, что атрибуты background и tag совпадают — фон для появления кнопки в пользовательском интерфейсе, а тег — для того, чтобы мы могли установить цвет краски в соответствии с тем, что пользователь щелкнул в коде Activity Java. Элемент включает метод для выполнения по нажатию кнопки — мы реализуем это в классе Activity в следующий раз. Мы также указываем рисование с именем «краска». Добавьте это в проект сейчас, создав новый файл в папке (-ях) для рисования проекта и назвав его «paint.xml». Введите следующий код в новый файл для рисования:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
<layer-list xmlns:android=»http://schemas.android.com/apk/res/android» >
<item>
<shape android:shape=»rectangle» >
<stroke
android:width=»4dp»
android:color=»#FF999999″ />
<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=»#FF999999″ />
<solid android:color=»#00000000″ />
<corners android:radius=»10dp» />
</shape>
</item>
</layer-list>
|
Это менее сложно, чем кажется на первый взгляд. Чтобы создать внешний вид кнопки с закругленными углами, мы используем два слоя Drawable Shape Drawables, один контур в виде прямоугольника, а другой — округленный штрих. Штрихи имеют серый цвет с прозрачностью посередине, через которую будет виден цвет фона для каждой кнопки (цвет фона — это цвет, представленный кнопкой).
Вернувшись в файл макета, в макет верхней строки в разделе цветовой палитры добавьте следующие элементы ImageButton, чтобы представить первые шесть цветов, используя структуру, которую мы обрисовали выше:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
<ImageButton
android:layout_width=»@dimen/large_brush»
android:layout_height=»@dimen/large_brush»
android:layout_margin=»2dp»
android:background=»#FF660000″
android:contentDescription=»@string/paint»
android:onClick=»paintClicked»
android:src=»@drawable/paint»
android:tag=»#FF660000″ />
<ImageButton
android:layout_width=»@dimen/large_brush»
android:layout_height=»@dimen/large_brush»
android:layout_margin=»2dp»
android:background=»#FFFF0000″
android:contentDescription=»@string/paint»
android:onClick=»paintClicked»
android:src=»@drawable/paint»
android:tag=»#FFFF0000″ />
<ImageButton
android:layout_width=»@dimen/large_brush»
android:layout_height=»@dimen/large_brush»
android:layout_margin=»2dp»
android:background=»#FFFF6600″
android:contentDescription=»@string/paint»
android:onClick=»paintClicked»
android:src=»@drawable/paint»
android:tag=»#FFFF6600″ />
<ImageButton
android:layout_width=»@dimen/large_brush»
android:layout_height=»@dimen/large_brush»
android:layout_margin=»2dp»
android:background=»#FFFFCC00″
android:contentDescription=»@string/paint»
android:onClick=»paintClicked»
android:src=»@drawable/paint»
android:tag=»#FFFFCC00″ />
<ImageButton
android:layout_width=»@dimen/large_brush»
android:layout_height=»@dimen/large_brush»
android:layout_margin=»2dp»
android:background=»#FF009900″
android:contentDescription=»@string/paint»
android:onClick=»paintClicked»
android:src=»@drawable/paint»
android:tag=»#FF009900″ />
<ImageButton
android:layout_width=»@dimen/large_brush»
android:layout_height=»@dimen/large_brush»
android:layout_margin=»2dp»
android:background=»#FF009999″
android:contentDescription=»@string/paint»
android:onClick=»paintClicked»
android:src=»@drawable/paint»
android:tag=»#FF009999″ />
|
Каждая кнопка идентична, кроме цветов, определенных в фоне и атрибутах тега. Добавьте следующие шесть в макет нижнего ряда:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
<ImageButton
android:layout_width=»@dimen/large_brush»
android:layout_height=»@dimen/large_brush»
android:layout_margin=»2dp»
android:background=»#FF0000FF»
android:contentDescription=»@string/paint»
android:onClick=»paintClicked»
android:src=»@drawable/paint»
android:tag=»#FF0000FF» />
<ImageButton
android:layout_width=»@dimen/large_brush»
android:layout_height=»@dimen/large_brush»
android:layout_margin=»2dp»
android:background=»#FF990099″
android:contentDescription=»@string/paint»
android:onClick=»paintClicked»
android:src=»@drawable/paint»
android:tag=»#FF990099″ />
<ImageButton
android:layout_width=»@dimen/large_brush»
android:layout_height=»@dimen/large_brush»
android:layout_margin=»2dp»
android:background=»#FFFF6666″
android:contentDescription=»@string/paint»
android:onClick=»paintClicked»
android:src=»@drawable/paint»
android:tag=»#FFFF6666″ />
<ImageButton
android:layout_width=»@dimen/large_brush»
android:layout_height=»@dimen/large_brush»
android:layout_margin=»2dp»
android:background=»#FFFFFFFF»
android:contentDescription=»@string/paint»
android:onClick=»paintClicked»
android:src=»@drawable/paint»
android:tag=»#FFFFFFFF» />
<ImageButton
android:layout_width=»@dimen/large_brush»
android:layout_height=»@dimen/large_brush»
android:layout_margin=»2dp»
android:background=»#FF787878″
android:contentDescription=»@string/paint»
android:onClick=»paintClicked»
android:src=»@drawable/paint»
android:tag=»#FF787878″ />
<ImageButton
android:layout_width=»@dimen/large_brush»
android:layout_height=»@dimen/large_brush»
android:layout_margin=»2dp»
android:background=»#FF000000″
android:contentDescription=»@string/paint»
android:onClick=»paintClicked»
android:src=»@drawable/paint»
android:tag=»#FF000000″ />
|
Измените цвета, если хотите, но убедитесь, что вы используете одно и то же значение цвета в качестве фона и тегов для каждой кнопки. Теперь вы должны увидеть макет на вкладке «Графический макет» в Eclipse:
Вывод
Мы завершили первую часть серии! В данный момент ваше приложение мало что сделает, но в следующей части мы реализуем функции рисования, выявляем и реагируем на сенсорное взаимодействие и позволяем пользователю выбирать цвета. В заключительной части мы расширим эту функциональность, чтобы пользователь мог стереть, выбрать размеры кисти и ластика, начать новый рисунок или сохранить текущий рисунок.
В следующих последующих уроках этой серии мы рассмотрим использование заливки рисунка в функциях рисования, непрозрачность и поддержку взаимодействия без прикосновения (например, трекбол, стилус и мышь). Вы сможете использовать эти более поздние учебные пособия, чтобы развить навыки, приобретенные в этой серии. Будьте на связи!