Другой способ обработки щелчка кнопки

Лабораторная №5

Счетчик ворон и светофор

Создайте новый проект с стандартными настройками. Для разнообразия в последнем окне мастера снимите флажок Backwards Compatibility (AppCompat). Мы не будем использовать никаких компонентов из библиотеки совместимости, поэтому можем обойтись без обратной совместимости. Это позволит нам существенно снизить размер установочного файла.

В прошлый раз мы использовали ImageButton. Сегодня будем работать с обычной кнопкой. В режиме Design подведите курсор к компоненту Button и перетащите его на форму. В результате ваших действий на форме появится стандартная кнопка с настройками по умолчанию. В правой части экрана у вас имеется окно Attributes, в котором вы можете настроить необходимые свойства для кнопки. По умолчанию студия присвоит значение button атрибуту ID, который идёт самым первым. Если временно переключиться в режим Text, то увидите, что на самом деле атрибут имеет значение @+id/button. Если в вашем приложении будет много кнопок, то студия будет генерировать имена button2, button3 и т.д. Не используйте подобные идентификаторы, а сразу давайте им говорящие имена - button_name, button_food. Атрибуту Text присвойте текст Поздороваться. Будет отлично, если вы добавите этот текст через ресурсы.

Если вы создали новый проект на основе шаблона Empty Activity, то там уже был компонент TextView с текстом Hello, World. Компонент TextView является текстовой меткой для вывода текста, который нельзя редактировать. В метке будем выводить приветствие после щелчка кнопки. В окне свойств удаляем текст из свойства Text, чтобы в текстовой метке ничего не было. Проследите, чтобы у него был идентификатор. Если в окне свойств ничего нет, то добавьте свой идентификатор, например, textView (в текстовом режиме @+id/textView).

Настройте взаимное расположение компонентов по своему желанию. Будем считать, что интерфейс программы готов - у нас есть кнопка для нажатия и текстовая метка для вывода сообщений.

Теперь нужно научиться писать код для щелчка кнопки. Переключитесь с режима Design на режим Text и найдите тег <Button>. Добавьте к нему еще одну строчку:

<Button android:id="@+id/buttonHello" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:onClick="onClick" android:text="Поздороваться" />

На самом деле это можно было сделать и через графическую модель. Переключитесь обратно в режим Design и найдите в свойствах кнопки пункт OnСlick. Там будет прописано имя метода, которое мы задали через XML (смотри рисунок выше). Пользуйтесь любым удобным вам способом.

Мы задали событие onClick для кнопки (щелчок) и теперь осталось написать обработчик события. Вы уже знаете, как в Android Studio быстро создать заготовку. В текстовом режиме устанавливаем курсор на строчке android:onClick="onClick" и нажимаем комбинацию Alt+Enter - студия сгенерирует шаблон метода в классе MainActivity.

public void onClick(View view) { }

Вставим код.

public void onClick(View view){ TextView helloTextView = (TextView)findViewById(R.id.textView); helloTextView.setText("Hello Kitty!");}

Этот код вам уже знаком, но текстовую метку мы объявляем и присваиваем ссылку на нужный компонент сразу в методе щелчка. Приложение у нас простое и доступ к текстовой метке больше нигде не осуществляется. Поэтому нет нужды объявлять переменную на уровне класса и инициализировать её в методе onCreate().

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

Полный текст кода.

import android.app.Activity;import android.os.Bundle;import android.view.View;import android.widget.TextView; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) {   super.onCreate(savedInstanceState);   setContentView(R.layout.activity_main); } public void onClick(View view) {   TextView helloTextView = findViewById(R.id.textView);   helloTextView.setText("Hello Kitty!"); }}

Ещё раз обратите внимание на строчку TextView helloTextView = findViewById(R.id.textView);. Метод findViewById() переводится как НайдиКомпонентПоИдентификатору и применяет тот же подход - вы указываете в параметре идентификатор ресурса и программа ищет подходящий компонент. В дальнейшем вы постоянно будете использовать данный код в своих программах.

Новички на первых порах часто делают элементарную ошибку - помещают строчку инициализации объекта до метода setContentView(). Запомните, сначала нужно вывести шаблон (R.layout.activity_main), а только потом кнопки, текстовые поля, переключатели и т.д. В нашем случае используется отдельный метод для кнопки, который формируется после метода setContentView(). Позже, в других проектах вы увидите стандартные приёмы инициализации объектов.

Другой способ обработки щелчка кнопки

На самом деле, способ обработки щелчка кнопки, показанный выше, является относительно новым для разработчиков. Google рекомендует использовать данный способ как удобный, требующий меньше кода и понятный для чтения. Но тем не менее вам придётся сталкиваться со старым способом, который берет свои корни от Java. Поэтому необходимо изучить и второй способ, чтобы понимать другие примеры.

Добавьте в проект новую кнопку и разместите под первой кнопкой. Подправьте несколько атрибутов, например, так.

<Button android:id="@+id/button_сounter" ... другие атрибуты android:text="Считаем ворон" />

Я поменял для кнопки текст и идентификатор, а также некоторые параметры, отвечающие за положение кнопки на экране. Переключитесь в графический режим и посмотрите, как выглядит кнопка. Обратите внимание, что атрибут android:onClick у второй кнопки мы уже не используем.

Снова открываем файл MainActivity.java и пишем следующий код сразу после объявления класса и до метода onCreate():

private Button mCrowsCounterButton;

Во время набора студия будет пытаться угадать, что вы хотите ввести. Активно используйте подсказки. Например, уже при первом вводе символа B студия предложит несколько вариантов на эту букву. Если нужное слово находится первым в списке, то нажимайте клавишу Enter, иначе выберите нужное слово из списка и потом уже нажимайте Enter. Это удобно при наборе длинных имён классов и переменных.

Google разработал целое руководство по наименованию переменных. Например, закрытая переменная на уровне класса должна начинаться с символа m (member), а далее идёт понятное название с заглавной буквы. Давайте попробуем придерживаться этого стиля.

После строчки setContentView(R.layout.activity_main); пишем:

mCrowsCounterButton = findViewById(R.id.buttonCrowsCounter);

Переходим к самому важному - обработчику щелчка кнопки. Нам понадобится дополнительная переменная-счётчик mCount, которая будет содержать число подсчитанных ворон (её необходимо разместить выше метода onCreate() рядом с переменной mCrowsCounterButton).

private int mCount = 0;

Мы создали переменную и сразу её инициализировали.

Теперь пишем обработчик щелчка кнопки, активно используя всплывающие подсказки для быстрого набора. Код добавляется в методе onCreate() после других строк, написанных ранее в этом методе.

Сначала начинаем вводим первые символы слова mCrowsCounterButton (можно маленькими буквами) и нажимаем Enter, если видим, что нужная подсказка появилась. После этого слова ставим точку и должны появиться опять подсказки, которые относятся к данной переменной. Начинаем вводим первые буквы слова setOnClickListener. Здесь тоже проблем обычно не возникает. На данный момент у нас получилась строка mCrowsCounterButton.setOnClickListener();. Ставим курсор внутри круглых скобок и набираем new OnClickListener. Здесь важно набрать символ O в верхнем регистре. Тогда у вас появится нужная подсказка типа View.OnClickListener{...} (android.view.View). Нажимаем Enter и получаем нужную заготовку, внутри которой вставляем код:

mCrowsCounterButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) {   helloTextView.setText("Я насчитал " + ++mCount + " ворон"); }});

Ранее мы объявили переменную helloTextView внутри метода onClick(), из которого она недоступна в других методах. Поэтому поступим с ней так же, как с кнопкой - объявим текстовую метку на уровне класса и инициализируем её в методе onCreate(). Сделайте это самостоятельно, создав переменную с именем mInfoTextView.

Запускаем приложение и начинаем щёлкать по кнопке. При каждом щелчке счётчик mCount будет увеличиваться на единицу и эта информация будет отображаться на экране.

Нет смысла дублировать код для одной текстовой метки. Поэтому для первой кнопки, которая здоровалась, код можно сократить.

public void onClick(View view) { mInfoTextView.setText("Hello Kitty!");}

Мы познакомились с новым способом обработки щелчка кнопки. Какой способ вы предпочтёте - зависит от ваших привычек и вкуса. Более того, есть ещё один способ, о котором можно прочитать в отдельной статье о кнопках.

Вдобавок, если подключить к проекту Java 8, то вместо кода с подключением слушателя, можно использовать лямбда-выражение. Студия сама предложит заменить код.

mCrowsCounterButton.setOnClickListener(v ->   mInfoTextView.setText("Я насчитал " + ++mCount + " ворон"));

Теперь у вас есть чрезвычайно полезное приложение Счётчик ворон.

Светофор

Для закрепления навыков создадим приложение чуть посложнее предыдущего, а также познакомимся с другими приёмами программирования. В качестве примера напишем программу под условным названием «Светофор». Интерфейс программы будет выглядеть следующим образом. На красном экране расположены три кнопки и одна текстовая надпись. При нажатии кнопок фон программы будет меняться на соответствующий цвет, который закреплён за определённой кнопкой.

Первые шаги вполне очевидны. Создаём новый проект на основе "Hello, World" и перетаскиваем с панели инструментов три кнопки. Когда будете размещать кнопку, попробуйте потаскать её по разным позициям внутри экрана активности. Вы будете замечать различные всплывающие линии, подсказывающие о стандартных отступах от края или о центральной оси по вертикали и горизонтали. Это удобно, когда вы точно знаете, где нужно разместить один компонент.

В нашем случае мы поступим иначе. Сначала просто перетащим три кнопки на экран, не думая о позиционировании. Далее в окне Component Tree выделяем три кнопки, удерживая клавишу Shift, вызываем контекстное меню и выбираем команды Center Horizontally и потом Center Vertically. Кнопки равномерно распределятся по экрану.

Контекстное меню можно вызвать и напрямую у кнопок на экране. Достаточно указателем мыши начертить ограничивающий прямоугольник вокруг всех кнопок и щёлкнуть правой кнопкой. Но у разметки ConstraintLayout наблюдается неприятное поведение - после выравнивания кнопок последующий щелчок кнопки сдвигает их. Если у вас такого эффекта не происходит, то пользуйтесь.

В окне Component Tree выделите строку button. У вас должно появиться окно свойств Properties. Давайте избавимся от стандартных идентификаторов, а будем сразу приучаться давать осмысленные имена. Например, для первой кнопки присвоим свойству id значение buttonRed вместо стандартного @+id/button

Для второй кнопки присвоим значение buttonYellow.

Аналогично настраиваем третью кнопку buttonGreen.

Теперь нам нужно заменить текст на кнопках на слова Красный, Жёлтый и Зелёный. Сделайте это на основе предыдущих уроков с помощью строковых ресурсов самостоятельно, для одной из кнопок. Затем рассмотрите второй способ, описанный ниже для второй и третьей кнопок.

В режиме Design это также можно сделать: выберите кнопку buttonRed. В окне свойств найдите свойство text. Рядом находится кнопка с многоточием. Щёлкните на кнопке. У вас откроется диалоговое окно Resources.

Нажмите на выпадающий список Add new resource для создания нового строкового ресурса и выберите New String Value.

В новом окне New String Value Resource в первом поле Resource Name введите название ресурса, например, jellow, а во втором поле Resource Value введите текст для кнопки (напр. Желтый). Остальные поля не трогаем. Аналогичным образом поступите с другой кнопкой (Зёленый).

Мы совсем забыли про элемент TextView. Исправим упущение. Разместим компонент под кнопками и снова сделаем выравнивание.

Пусть на нём выводится текст, извещающий о текущем цвете фона приложения. Так как в ресурсах у нас уже есть слова Красный, Жёлтый и Зелёный, изначально предназначенные для кнопок, то мы не будем создавать новые строковые ресурсы, а воспользуемся готовыми наработками. По умолчанию у нас используется красный цвет. В окне свойств выбираем свойство text для TextView и нажимаем кнопку с многоточием для вызова знакомого диалогового окна. На этот раз мы не будем щёлкать на кнопке New Resource, а сразу выберем строку red, которая, как мы помним, содержит текст Красный и щёлкнем кнопку OK (можно сделать сразу двойной щелчок на строке).

Заодно рассмотрим другую настройку под ней с изображением гаечного ключа и таким же названием text. Представьте себе, что в реальной программе изначально у TextView нет никакого текста, он будет сформирован позже программно. Но чтобы разработчик видел, как будет выглядеть дизайн экрана, ему нужно видеть текст на этапе проектирования. Для этих целей и предназначена вторая настройки для текста. Подобное вы можете увидеть и у других свойства компонента.

С текстом разобрались. Но где остальные настройки? В окне свойств Properties нажмите на ссылку View all properties. Тут увидите все доступные атрибуты для компонента. Если вы не помните точное название, то воспользуйтесь поиском. Выбираем нужное значение из выпадающего списка. Студия предлагает варианты, которые рекомендованы по правилам Material Design. Если вы хотите установить своё значение, то переключитесь в режим Text и вручную поменяйте значение. Если этого не сделать, а пытаться отредактировать значение в режиме Design, то студия не будет реагировать.

Рекомендую постоянно переключаться в режим Text и смотреть, что происходит в коде. Это позволит вам увереннее разбираться в коде и читать чужой код. Как правило, новички предпочитают работать через визуальные инструменты, а программисты с опытом самостоятельно пишут практически весь код. Нужно найти разумный баланс между двумя подходами. Всё придёт со временем.

Со строками вроде разобрались. Давайте теперь в ресурсах зададим цвета для фона программы. Ресурсы для цветов принято хранить в отдельном файле res/values/colors.xml, хотя технически никто не запрещает хранить их в том же файле strings.xml.

Откроем указанный файл и добавим ресурс жёлтого цвета между тегами resources:

<color name="yellowColor">#FFFF00</color>

Слева появится жёлтый квадрат, по нему легко видеть цвет заданного ресурса.

По такому же принципу добавьте зелёный цвет.

<color name="greenColor">#FF00FF00</color>

Самостоятельно добавьте ресурс для красного цвета под именем redColor.

Если вам знаком такой формат цвета, то трудностей добавление новых цветов подобным способом вам не доставит. Если нужно выбрать более сложный цвет, то проще воспользоваться мастером, как мы это делали в "Hello Kitty", когда выбирали розовый цвет, а затем полученный цвет скопировать в ресурсы.

Определив в ресурсах все необходимые цвета, можно сразу присвоить красный цвет для контейнера ConstraintLayout. В окне свойств находим для данного элемента свойство background (чтобы увидеть все свойства компонента, нажмите ссылку View all properties). Снова нажимаем кнопку с тремя точками, чтобы открыть диалоговое окно. В окне выбираем раздел Color и ищем свой ресурс redColor.

Если посмотреть в текстовом режиме, то увидите строчку android:background="@color/redColor" для тега ConstraintLayout. Так как мы будем менять фон у ConstraintLayout, то присвоим ему идентификатор.

Общий каркас приложения завершен. У нас есть три кнопки с соответствующими текстами, текстовая надпись со словом Красный, и красный фон, используемый в контейнере ConstraintLayout. Пора приступать к программной логике программы. А пока можно запустить приложение, чтобы убедиться, что мы не сделали ошибок в разметке.

Наша задача - обработать щелчки трёх кнопок и менять цвет фона приложения, а также текст в TextView. Ранее мы уже познакомились с удобным способом обработки события onClick. Давайте закрепим пройденный материал и повторим тот же код для первой кнопки. Пропишем вручную событие onClick в теге Button:

android:onClick="onRedButtonClick"

Вспоминаем - в режиме Text помещаем курсор на названии метода и нажимаем комбинацию Alt+Enter, чтобы создать заготовку щелчка первой кнопки в классе MainActivity.

Объявим переменные в классе и получим к ним доступ в методе onCreate():

// до метода onCreate()private ConstraintLayout mConstraintLayout;private TextView mInfoTextView; // в методе onCreate()mConstraintLayout = (ConstraintLayout) findViewById(R.id.constraintLayout);mInfoTextView = (TextView) findViewById(R.id.textViewInfo);

Напоминаю, что код нужно писать вручную, а не копировать. Тогда многие вопросы отпадут и вам не придётся бежать с криками, что ничего не работает J.

Раньше в студии по умолчанию использовался компонент RelativeLayout и пример был написан под него. Новички размещали кнопки в ConstraintLayout, а в код вставляли строчки:

private RelativeLayout mRelativeLayout;mRelativeLayout = (RelativeLayout)findViewById(R.id.relativeLayout);

Для не слишком догадливых подчёркиваю - ConstraintLayout и RelativeLayout - это разные вещи.

Пишем код для щелчка кнопки с надписью "Красный":

public void onRedButtonClick(View view) { mInfoTextView.setText(R.string.red); mConstraintLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.redColor));}

Мы обращаемся к созданным ресурсам через специальный класс R и через точку указываем тип ресурсов, а затем имя ресурса.

Для кнопки "Зелёный" напишите код самостоятельно, добавив метод onGreenButtonClick().

Для кнопки "Жёлтый" напишем код в традиционной манере через слушателя OnClickListener. В методе onCreate() добавляем:

Button yellowButton = (Button) findViewById(R.id.buttonYellow);yellowButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) {   mInfoTextView.setText(R.string.yellow);   mConstraintLayout.setBackgroundColor(ContextCompat           .getColor(MainActivity.this, R.color.yellowColor)); }});

Раньше для изменения кода использовался код:

mRelativeLayout.setBackgroundColor(getResources().getColor(R.color.redColor));

В Android 6 (API 23) метод getColor(int id) объявили устаревшим и студия теперь подчёркивает данный метод. Можно заменить на один из двух вариантов:

// у второго параметра используем значение nullmRelativeLayout.setBackgroundColor(getResources().getColor(R.color.yellowColor, null)); // используем метод из библиотеки совместимостиmRelativeLayout.setBackgroundColor(ContextCompat.getColor(MainActivity.this, R.color.yellowColor));

Первый вариант подойдёт, если вы не поддерживаете старые устройства, а сразу пишете приложение для телефонов с API 23. Второй способ более универсальный. Запускаем приложение и щёлкаем по кнопкам - текст в надписи и фон в приложении должны меняться в соответствии с нажатой кнопкой.

Полный текст кода будет выглядеть следующим образом:

import android.os.Bundle;import android.support.constraint.ConstraintLayout;import android.support.v4.content.ContextCompat;import android.support.v7.app.AppCompatActivity;import android.view.View;import android.widget.Button;import android.widget.TextView; public class MainActivity extends AppCompatActivity { private ConstraintLayout mConstraintLayout; private TextView mInfoTextView; @Override protected void onCreate(Bundle savedInstanceState) {   super.onCreate(savedInstanceState);   setContentView(R.layout.activity_main);    mConstraintLayout = (ConstraintLayout) findViewById(R.id.constraintLayout);   mInfoTextView = (TextView) findViewById(R.id.textViewInfo);    Button yellowButton = (Button) findViewById(R.id.buttonYellow);   yellowButton.setOnClickListener(new View.OnClickListener() {       @Override       public void onClick(View v) {           mInfoTextView.setText(R.string.yellow);           mConstraintLayout.setBackgroundColor(ContextCompat                   .getColor(MainActivity.this, R.color.yellowColor));       }   }); } public void onRedButtonClick(View view) {   mInfoTextView.setText(R.string.red);   mConstraintLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.redColor)); } public void onGreenButtonClick(View view) {   mInfoTextView.setText(R.string.green);   mConstraintLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.greenColor)); }}

В качестве задания упростите код для трёх кнопок, создав для них общий метод onClick()


Дата добавления: 2019-01-14; просмотров: 337; Мы поможем в написании вашей работы!

Поделиться с друзьями:




Мы поможем в написании ваших работ!