Счетчик нажатий android studio

Щелчок кнопки/Счётчик ворон

Первоначально в статье использовались примеры на Java, которые оставил для истории. Настало время переписать материал.

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

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

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

Теперь нужно научиться писать код для щелчка кнопки.

Откройте файл класса MainActivity и в методе onCreate() напишите код.

Этот код вам уже знаком по предыдущему занятию. Если вы набирали текст самостоятельно, то у вас всё получится. Если просто скопировали и получили ошибки, то разбирайтесь сами. Я лентяям не помогаю.

Запускаем проект и нажимаем на кнопку, чтобы увидеть результат. Можете изменить текст по своему желанию, например, на Ты кто такой? Давай, до свидания!, но это сообщение будет выглядеть мягко говоря, странным.

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

Альтернативные варианты

Существуют альтернативные варианты для обработки щелчка кнопки, которые могут встретиться вам в интернете. Со временем вы сами выберите удобный вам стиль.

Например, кнопку и метку можно объявить стандартным Java-способом через метод findViewById() и затем подключать слушатель к кнопке.

На самом деле Java-стиль в Kotlin практически никто не использует. А вот ещё пара примеров для Kotlin.

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

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

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

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

В методе onCreate() после кода для первой кнопки пишем:

Ещё раз напоминаю, не копируйте текст со страницы, а вводите текст вручную. Так вы быстрее освоите программирование, кроме того научитесь пользоваться системой подсказок и уменьшите количество опечаток.

В этом примере мы создали дополнительную переменную-счётчик counter, которая будет содержать число подсчитанных ворон. После создания мы сразу её инициализировали.

В обработчике щелчка мы увеличиваем значение счётчика через оператор инкремента ++, который ставим перед переменной. Попробуйте разместить оператор после переменной и посмотреть на результат, так вы поймёте разницу от местоположения оператора у переменной.

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

Теперь у вас есть чрезвычайно полезное приложение Счётчик ворон. Если преподаватель вас неожиданно спросит на занятии, почему вы смотрите в окно с рассеянным видом, вы можете смело достать свой телефон и сказать, что заняты очень важным делом — считаете ворон.

Впрочем, программа получилась у нас универсальной, можно считать не только ворон за окном.

Исправляем ошибки

На первых порах новички делают элементарные ошибки — опечатки, копирование куска кода без его понимания, пишут не в том месте и т.д. Студия пытается по мере возможностей подсказать вам, но не все обращают внимание на предупреждения, а потом пишут письма с просьбой разобраться. Небольшой ликбез по нахождению ошибок. В редакторе кода в верхнем правом углу есть прямоугольник. Он может быть зелёным (идеальный код), жёлтым (не смертельно, но лучше исправить) и красным (ошибка в коде, программа не запустится).

Читайте также:  Андроид для акура мдх

Ваша задача — стремиться к зелёному цвету. Жёлтый цвет желательно просматривать и решать самостоятельно, нужно ли исправлять код. Если вы понимаете в чём проблема, то исправьте. Если не понятно, то оставьте. Предупреждения не всегда бывают по делу, иногда их можно игнорировать. Понимание придёт с опытом и практикой.

Ниже показан случай, когда я сделал опечатку в названии класса String.

Помимо прямоугольника, там же ниже есть зарубки с такими же цветами. Подведите курсор мыши к любой из зарубок и увидите подсказку о характере ошибки или предупреждения. Щелчок по зарубке перенесёт вас в нужное место в документе.

Домашнее задание

Добавьте в проект ещё одну кнопку, чтобы считать отдельно котов и ворон. Далее запускаете видео и считаете.

Пример на Java

Добавьте на экран кнопку (смотри пример на Kotlin). Переключитесь с режима Design на режим Text и найдите тег . Добавьте к нему ещё одну строчку:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Ещё раз напоминаю, не копируйте текст со страницы, а вводите текст вручную. Так вы быстрее освоите программирование, кроме того научитесь пользоваться системой подсказок и уменьшите количество опечаток.

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

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

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

Читайте также:  How to support android

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

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

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

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

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

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

Источник

Полный список

— обрабатываем нажатия на виджет

Продолжаем тему виджетов. Виджет, который показывает информацию – это хорошо, это мы теперь умеем. Но кроме этого виджет еще умеет реагировать на нажатия.

Т.к. прямого доступа к view-компонентам виджета мы не имеем, то использовать, как обычно, обработчики нажатий не получится. Но RemoteViews, используемый нами для работы с view, позволяет настроить реакцию view на нажатие. Для этого он использует PendingIntent. Т.е. мы можем на нажатие на виджет повесить вызов Activity, Service или BroadcastReceiver. В этом уроке сделаем непростой, но достаточно содержательный пример, отражающий различные техники реагирования на нажатия.

Создадим виджет, состоящий из двух текстов и трех зон для нажатий.

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

Первая зона будет по клику открывать конфигурационное Activity. Это пригодится в том случае, когда вы хотите дать пользователю возможность донастроить виджет после установки. Конфигурировать будем формат отображаемого в первой строке времени.

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

Каждое нажатие на третью зону будет увеличивать на единицу счетчик нажатий и обновлять виджет. Тем самым будет меняться второй текст, отображающий текущее значение счетчика.

Для простоты, конечно, можно было разбить этот пример на три отдельных виджета. Но я решил сделать все в одном, чтобы наглядно показать, что один виджет может совершать разные действия в ответ на нажатия на разные view.

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

Project name: P1201_ClickWidget
Build Target: Android 2.3.3
Application name: ClickWidget
Package name: ru.startandroid.develop.p1201clickwidget

Layout-файл виджета widget.xml:

Первые два TextView – это тексты, а последние три – зоны нажатия.

Layout-файл для конфигурационного экрана config.xml:

Поле для ввода формата даты и кнопка подтверждения

Класс конфигурационного экрана ConfigActivity.java:

Тут ничего нового для нас нет.

В onCreate мы извлекаем и проверяем ID экземпляра виджета, для которого открылся конфигурационный экран. Далее формируем отрицательный ответ на случай нажатия кнопки Назад. Читаем формат времени и помещаем его в EditText. Читаем значение счетчика и, если это значения еще нет в Preferences, то пишем туда 0.

В onClick мы сохраняем в Preferences формат из EditText, обновляем виджет, формируем положительный ответ и выходим.

Код обновления виджета пока закоментен, т.к. у нас еще нет класса MyWidget. Сейчас создадим и можно будет раскоментить.

Класс виджета MyWidget.java:

А вот тут уже немного посложнее.

В onUpdate мы обновляем все требующие обновления экземпляры, в onDelete подчищаем Preferences после удаления экземпляров.

Метод updateWidget отвечает за обновления конкретного экземпляра виджета. Здесь мы настраиваем внешний вид и реакцию на нажатие.

Сначала мы читаем настройки формата времени (которые были сохранены в конфигурационном экране), берем текущее время и конвертируем в строку согласно формату. Также из настроек читаем значение счетчика. Создаем RemoteViews и помещаем время и счетчик в соответствующие TextView.

Далее идет настройка обработки нажатия. Механизм несложен. Сначала мы готовим Intent, который содержит в себе некие данные и знает куда он должен отправиться. Этот Intent мы упаковываем в PendingIntent. Далее конкретному view-компоненту мы методом setOnClickPendingIntent сопоставляем PendingIntent. И когда будет совершено нажатие на этот view, система достанет Intent из PendingIntent и отправит его по назначению.

В нашем виджете есть три зоны для нажатия. Для каждой из них мы формируем отдельный Intent и PendingIntent.

Читайте также:  This cannot be undone андроид что делать

Первая зона – по нажатию должно открываться конфигурационное Activity. Создаем Intent, который будет вызывать наше Activity, помещаем данные об ID (чтобы экран знал, какой экземпляр он настраивает), упаковываем в PendingIntent и сопоставляем view-компоненту первой зоны.

Вторая зона – по нажатию должен обновляться виджет, на котором было совершено нажатие. Создаем Intent, который будет вызывать наш класс виджета, добавляем ему action = ACTION_APPWIDGET_UPDATE, помещаем данные об ID (чтобы обновился именно этот экземпляр), упаковываем в PendingIntent и сопоставляем view-компоненту второй зоны.

Третья зона – по нажатию должен увеличиваться на единицу счетчик нажатий. Создаем Intent, который будет вызывать наш класс виджета, добавляем ему наш собственный action = ACTION_CHANGE, помещаем данные об ID (чтобы работать со счетчиком именно этого экземпляра), упаковываем в PendingIntent и сопоставляем view-компоненту третьей зоны.

Теперь при нажатии на первую зону будет вызван конфигурационный экран. По нажатию на вторую будет обновлен виджет. А вот нажатие на третью ни к чему не приведет, т.к. наш класс MyWidget знает, как работать с Intent с action вида ACTION_APPWIDGET_UPDATE, ACTION_APPWIDGET_DELETED и пр. А мы ему послали свой левый action.

Значит надо научить его понимать наш Intent. Вспоминаем, что MyWidget – это расширение AppWidgetProvider, а AppWidgetProvider – это расширение BroadcastReceiver. А значит, мы можем сами реализовать метод onReceive, в котором будем ловить наш action и выполнять нужные нам действия.

В методе onReceive мы обязательно выполняем метод onReceive родительского класса, иначе просто перестанут работать обновления и прочие стандартные события виджета. Далее мы проверяем, что intent содержит наш action, читаем и проверяем ID из него, читаем из настроек значение счетчика, увеличиваем на единицу, пишем обратно в настройки и обновляем экземпляр виджета. Он прочтет новое значение счетчика из настроек и отобразит его.

Вы обратили внимание, что при создании PendingIntent мы использовали ID экземпляров виджета в качестве requestCode? Поясняю, зачем это сделано. Допустим, мы создаем два экземпляра виджета. Первый создается и создает свои PendingIntent для обновления, счетчика и конфигурирования. Эти PendingIntent содержат action и extra-данные. Теперь создается второй экземпляр. Он также пытается создать свои PendingIntent с теми же action и другими extra-данными. Тут мы вспоминаем прошлый урок, а именно дефолтное поведение системы. Если создаваемый PendingIntent похож на существующий, то создаваемый станет копией уже существующего. Т.е. все PendingIntent второго экземпляра получат extra-данные из Intent первого. В extra-данных у нас лежит ID экземпляра. Значит второй экземпляр виджета будет обновлять время/счетчик и открывать конфигурационный экран первого экземпляра. Если интересно, можете поставить нули вместо ID при создании PendingIntent и убедиться, что так все и будет. Чтобы избежать этого, используем requestCode. Надеюсь, что этот момент понятен, т.к. для этого и была написана бОльшая часть прошлого урока )

Теперь не забудьте раскаментить код обновления виджета в классе ConfigActivity в методе onClick. Иначе ничего работать не будет.

Создадим файл метаданных xml/widget_metadata.xml:

Виджет будет вертикальным. Число 0 – в updatePeriodMillis говорит о том, что виджет не будет обновляться системой. Мы его сами обновлять будем.

Осталось прописать классы в манифесте. Должен получиться примерно такой фрагмент кода:

Если для Receiver не указана иконка и текст, он возьмет их из приложения.

Т.е. наш виджет будет иметь стандартную системную иконку и имя приложения – ClickWidget.

Все сохраняем и инсталлим приложение.

Для наглядности давайте создадим пару экземпляров виджета. Настройки в конфигурационном экране пока оставляйте дефолтными.

Виджеты отображают время, когда они были последний раз обновлены и счетчик нажатий.

Теперь понажимайте Update на обоих виджетах, время будет обновляться. А, нажимая Count, вы меняете значение счетчика, и виджет это отображает. Вместе со счетчиком, кстати, актуализируется и время, т.к. оно актуализируется при каждом обновлении виджета.

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

а второй – секунды

Предлагаю вам самостоятельно допилить виджет так, чтобы при нажатии на Count обновлялся только счетчик, а время не менялось. Также попробуйте добавить еще одну (четвертую) зону, по нажатию на которую открывался бы, например, www.google.com в браузере.

На всякий случай проговорю явно следующее. В нашем примере мы при нажатиях вызывали через Intent свои же классы. Но, думаю, всем понятно, что можно вызывать все, что позволит Intent, никаких ограничений нет.

На следующем уроке:

— создаем виджет со списком

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

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

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

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

— новый чат Performance для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме

Источник

Оцените статью