Смотрите видеоурок бесплатно на удобной для вас платформе:
Обзор статьи
В этой статье вы научитесь вручную создавать новый компонент Activity в своем проекте, а потом сделаем первые шаги в сторону изучения навигации между экранами. Мы будем не только переключаться между двумя Activity, но и передавать примитивные типы данных, такие как строки или числа. А самое вкусное – передачу сложных типов данных, то есть объектов, оставим на следующую часть этого цикла уроков про важнейший компонент операционный системы.
Не беспокойтесь, вы обязательно научитесь разбираться в правилах этой игры как боженька, но всему свое время. Ну а ускорить достижение своих целей вы можете с помощью понятной программы в рамках AndroidSprint, заглядывайте в описание. Приступим.
На уроке с обзором компонентов мы определили, что концептуально Activity – это системный компонент, который представляет экран. Область на устройстве, которая что-то отображает и с чем можно взаимодействовать предоставляется компонентом Activity. За исключением statusbar и navbar – технически эти элементы являются частью системного интерфейса.
Причем взаимодействовать можно не обязательно с запущенным приложением. Рабочий стол с иконками приложений тоже является приложением, только системным (это называется Launcher). И в нем тоже за отображение элементов отвечает Activity.
Создание нового Activity
А начать свое повествование про этот ключевой компонент я хочу с демонстрации создания нового Activity. Вероятно вы слышали, что в разработке приложений популярен подход Single Activity. Это когда есть единое Активити и множество фрагментов (о них будет, конечно же, в следующих уроках).
Однако, во первых – в сложных многомодульных проектах порой не обойтись без создания новых Activity. А во-вторых – эта тема безусловно затрагивается на собеседованиях, в том числе и на нашем практикуме, это так скажем, базовая информация, которой нужно владеть.
Итак, на самом деле создать новый компонент Activity можно в пару кликов. Достаточно в нашем рабочем каталоге нажать New → Activity → (и если выбрать) Empty Views Activity, то откроется флоу, аналогичный тому, что появляется при создании нового проекта.
В первой строке вводится название своего Activity, ниже автоматически генерируется название для файла разметки. Однако, я не буду прожимать Finish, а все таки хочу сделать все вручную, чтобы продемонстрировать этот несложный процесс. Вам необходимо понимать как это работает и что генерирует среда разработки.
Вот алгоритм создания:
- Создаю файл с классом Activity в рабочем каталоге. У меня это будет FirstDemoActivity (причем постфикс Activity обязателен). Наследуюсь от
AppCompatActivity()
. Обращу внимание, наследоваться от простого класса Activity нельзя. AppCompat — это библиотека , которая дает возможность использовать фичи из новых версий Android в более старых. Условно это способ заставить приложение корректно работать на старых устройствах. - Далее создаю файл разметки для текущей Activity. Нейминг должен быть в характерном для XML стиле snake case, а еще слово Activity должно быть в качестве префикса. В самом лейауте размещу какой-нибудь идентифицирующий текст.
- Возвращаюсь в класс и переопределяю метод жизненного цикла
onCreate()
, чтобы в нем связать код класса с разметкой. Делается это в методеsetContentView()
. В параметрах обращаемся к классу R, указываем, что это лейаут и далее название. А о жизненном цикле обязательно поговорим уже скоро. - Наконец, самый важный момент. Activity не будет отображаться ни при каких обстоятельствах, если его не зарегистрировать в манифесте. Поэтому идем туда и в главном теге
application
добавляем еще один тег с нашейactivity
.
Это все шаги по созданию нового компонента. Причем обратите внимание, action
и category
с параметрами MAIN
и LAUNCHER
относятся к MainActivity – это говорит системе о том, что при запуске приложения именно это Activity должно открываться. Для демонстрации давайте перенесу блок с интент фильтрами в наш FirstDemoActivity, добавлю параметр, который просит система и запущу приложение. На основной функционал это не повлияет, так как коммитить изменения буду в отдельную ветку с номером соответствующего урока. Открывается демо экран, все хорошо.
Навигация между двумя Activity
Окей, мы научились создавать кастомную Активити и запускать ее. Теперь предлагаю разобраться как переключаться между двумя активити в рамках одного приложения. Для этого я создам еще один такой же компонент с помощью средств среды разработки и назову его SecondDemoActivity.
В разметке также добавлю кнопки навигации и повешу пустые слушатели для них в обоих файлах. Вы спросите почему я не продолжаю реализацию основного проекта, а для демонстрации создаю пустые экраны? Экраны приложения для изучения иностранных слов будут реализовываться на фрагментах. То есть будет использоваться подход Single Activity. Именно на этом принципе построен спринт по разработке приложения для хранения рецептов в рамках практикума AndroidSprint. С дополнительными внутренними уроками, которых нет в паблике. С менторством “здорового человека” и с карьерным развитием до получения оффера. Ознакомьтесь по ссылкам в описании.
Способы перехода на другую Activity
Великолепно! У нас есть две Activity. Как по кнопке перейти на другую? Когда у моего подопечного возникает сложный комплексный вопрос, я всегда предлагаю ему декомпозировать проблему на более мелкие. Объяснение начну по такому же принципу.
Переходы между экранами (не важно это будут Фрагменты или Активити) в целом можно поделить на три группы:
- Обычный переход на новый экран без передачи данных.
- Переход на новый экран с передачей на него каких-либо данных. Например, при регистрации, сначала вас просят ввести имя, вы жмете “Далее”, на следующем экране уже отображается введенное вами имя и вас просят ввести другие данные.
- Переход на новый экран с ожиданием результата. В этом случае подразумевается, что после запуска другого экрана приложение ждет определенных действий от пользователя, чтобы получить результат. Пример, если нужно установить аватарку в приложении и вы выбираете опцию «Загрузить из галереи», открывается системная Activity с галереей. В этот момент приложение «ожидает результата» — оно ждет, когда пользователь выберет изображение. После выбора изображения система возвращает результат в виде URI, который можно использовать для загрузки изображения в нужное место в интерфейсе.
В ближайшее время будем рассматривать переход между экранами и передачу различных данных между ними.
Стоит заметить, мы сейчас никак не касаемся управлением навигацией, например, с помощью Jetpack Navigation. При использовании этих технологий реализация и передача данных будет отличаться.
Intent (интенты / намерения) в Андройд. Переход без данных.
К практике! Чтобы реализовать классический переход с одной Активити на другую необходимо создать объект Intent. Слово переводится, как “намерение”. Это простой способ сказать системе о своем намерении что-то сделать.
- Сначала создаю объект. В параметрах конструктора отправляю контекст текущей Активити с помощью this, вторым параметром пункт назначения.
::class
— это способ в Kotlin получить ссылку на классSecondDemoActivity
. Это как указатель на класс, который мы хотим использовать..java
— добавляется для получения Java-совместимого объектаClass
. Это нужно, чтобы Android мог правильно работать с классами, так как Android требует именно класс java, а не Kotlin.- Вторым шагом просто вызываю метод из системного класса Activity
startActivity()
с параметромintent
. Таким образом мы сначала объявили намерение, а теперь говорим системе “сделай это”.
binding.btnOpenSecond.setOnClickListener {
val intent = Intent(this, SecondDemoActivity ::class.java)
startActivity(intent)
}
Продублирую логику на втором экране, чтобы можно было возвращаться на первый экран. Запускаю приложение и жму на кнопку перехода – все работает.
Явный (explicit) и неявный (implicit) интенты
Еще пара слов про Intent
. То, что мы сейчас написали – пример так называемого явного интента (explicit intent). Это интент, в котором явно указывается компонент, который нужно запустить. То есть указывается его полное имя класса, как в нашем случае.
Неявные Intent
объекты (implicit intent) не указывают конкретное приложение или компонент для выполнения задачи. Вместо этого они описывают общее действие, которое может быть выполнено любым приложением, поддерживающим эту задачу. Например, если вы хотите открыть веб-страницу, вы можете создать неявный Intent
, который позволит любому установленному браузеру открыть указанный URL.
Способы передачи данных между Activity в Android
Хорошо. Теперь попробуем перекинуть данные с одного экрана на другой. Здесь уже интереснее, так как существует несколько способов передачи данных напрямую. Подчеркиваю – напрямую, то есть без использования стейтов, вью моделей, баз данных и так далее. У каждого есть преимущества и ограничения.
Использование Intent с Extras для передачи примитивных типов данных
В этом уроке мы рассмотрим использование Intent для передачи примитивных типов данных. Этот способ подразумевает добавление определенных Extras (то есть “добавлений”) к нашему созданному интенту.
Чаще всего используется для легких данных в виде строк, чисел или Boolean флагов. Также можно передавать массивы и списки из примитивов, но объекты без дополнительной обработки передать не получится.
Как отправить данные:
Чтобы добавить Экстра нужно обратиться к созданной переменной интента и вызвать метод putExtra()
. Сейчас важно – зафиксируем ключевую мысль. Основным способом напрямую передать данные в другую активити является создание специального объекта Bundle. Остальные способы являются дополнительными и точно также передают бандл неявно. Один из таких простых способов – метод putExtra()
.
Если провалимся в место его объявления, то убедимся, что внутри создается объект Bundle()
. Подробнее бандлы мы рассмотрим, когда будем передавать через него не только примитивы, но и объекты. Тогда мы будем даже создавать такие объекты напрямую самостоятельно, а пока просто запомните это и воспринимайте putExtra()
, как своего рода обертку над созданием и упаковкой этого объекта для передачи данных.
Хорошо. У метода будет два параметра.
- В первый надо положить уникальную строку. Ключ-идентификатор по которому эти данные мы сможем получить на новом экране. По сути это просто строка, но она должна быть уникальной.
- Вторым параметром отправляются сами данные того типа, которого хотим отправить.
Для наглядности передам во вторую Активити два значения: строку и число. Как видите, метод putExtra()
вызывается поочередно для каждого передаваемого значения. Мы как бы упаковываем интент (на самом деле внутри упаковывается бандл — слово так и переводится, как “набор”, “пачка” или “связка”).
binding.btnOpenSecond.setOnClickListener {
val intent = Intent(this, SecondDemoActivity::class.java)
intent.putExtra("EXTRA_KEY_TEXT", "don't panic")
intent.putExtra("EXTRA_KEY_NUMBER", 42)
startActivity(intent)
}
Как получить данные:
Для начала добавлю два TextView в макете для будущих передаваемых данных. При желании их можно просто вывести в консоль с помощью логов.
- Чтобы получить данные в SecondDemoActivity сперва нужно вызвать метод получения интента, который был адресован к этой Активити –
getIntent()
. Сразу же студия предлагает использовать более простой синтаксис и обращаться к свойству класса Activity –intent
. - Далее, если у проперти начать вводить вызов метода со значения
get
вывалится куча предложений с тем, что мы хотим получить. Здесь отталкиваемся от типа Extra, которые передавали. Для строки будем использоватьgetStringExtra
, а для целого числаgetIntExtra
соответственно. - В параметры указываем тот самый ключ, по которому отправляли экстра данные. Правильно будет сохранить ключи в константы и использовать их во всем проекте глобально во избежание ошибок.
- Для получения целочисленного значения требуется второе значение по умолчанию, поставлю 0. Можем провалиться в исходник и посмотреть на сигнатуру, там так и написано.
Все. Теперь эти данные просто помещу в отдельные переменные для их отображения на экране. Запускаем для проверки. Вот мы на первом экране, переходим на второй и видим, что данные успешно переданы и отображены на новой Активити.
Это было не сложно, но одновременно с этим отлично демонстрирует концепцию передачу данных между компонентами, которая будет использоваться и далее.
Для тех, кто собрался стать Android-разработчиком
Пошаговая
схема
Описание процесса обучения от основ Kotlin до Android-разработчика
Бесплатные
уроки
Авторский бесплатный курс по основам языка программирования Kotlin
Обучающий
бот
Тренажер и самоучитель по Котлин – бесплатные тесты и практика