Как связать два активити в android studio

Обновлено: 23.09.2022

Можно ли в Android Studio сделать так, чтобы два файла(.kt или .java) с кодом работали на одном layout. Просто если местами менять их в файле манифеста, то код каждого файла работает, но по отдельности. В обоих файлах содержаться кнопки, прогресс бар и т.д

скажите пожалуйста, ваши активити выполняют одинаковые функции, или хотя-бы приблизительно одинаковые? просто стоит задуматься о том чтобы провести слияние этих двух классов в один, просто добавить несколько условных операторов.

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

в функции onCreate есть метод setContentView в котором вы указываете файл разметки. А почему крашится приложение известно, может попытаться решить эту проблему, и проблема с использованием одного layout решится тоже?

а может вынести методы из вашего класса в отдельный класс, чтобы ваш коллега к отдельному классу обращался?

1 ответ 1

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

Так же нужно понимать, что две активности не могут жить одновременно и уж тем более обращаться к вью-элементам и методам друг друга.
Одна активность может запустить другую методами startActivity(. ) и startActivityForResult(. ) и передать в неё какие-то данные через Intent , а при запуске вторым вариантом получить какие-то данные обратно.

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

Продолжаем курс по обучению основам разработки мобильных приложений в Android Studio на языке Kotlin.

В этом уроке создадим второй экран в приложении, и настроим взаимодействие между экранами с передачей данных.

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

Продолжаем разработку приложения на языке Kotlin, которое мы делали на прошлом уроке. Исходный код можно скачать на странице прошлого урока.
Пока что наше приложение имеет только один экран. В этом уроке мы добавим второе активити, которое будет отображать экран с данными, полученными на основе данных с первого экрана. При нажатии кнопки Random будет отображаться окно со случайным числом от нуля до текущего значения счетчика.

Вы узнаете

  • Как запустить новое активити с помощью интента
  • Как передать данные во второе активити через интент
  • Как получить данные, переданные через интент во втором активити

Создаем новое активити


  1. Раскройте пакет с именем com.example.android.myfirstapp по пути apps >java >com.example.android.myfirstapp.
  2. Правым кликом выберите команду File >New >Activity >Empty Activity.
  3. В окне настроек нового активити установите для него имя SecondActivity. Убедитесь, что в поле Source Language установлен Kotlin.

4. Нажмите Finish. Android Studio создаст файл на языке Kotlin и файл макета на языке XML для нового активити.

Изучите файл манифеста


  1. Откройте файл манифеста приложения по пути app >manifests >AndroidManifest.xml.Файл манифеста содержит информацию о приложении, включая список всех активити.
  2. Обратите внимание на текст между тегами для MainActivity:Как видите, тег содержит параметр имени активити. MainActivity запускается после при старте приложения, поэтому включает дополнительные параметры, которые определяют его как стартовое активити.
  3. Изучите тег для второго активити. Он содержит только параметр имени.

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

Изучите файл Kotlin нового активити

  1. Откройте файл SecondActivity.kt.
  2. Обратите внимание на метод onCreate(). Постмотрите на вызов setContentView(). Этот метод указывает файл макета activity_second.xml как разметку нового активити.

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

Создаем макет для нового активити

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



Добавьте TextView для заголовка


  1. Откройте файл activity_second.xml. Вы увидите пустой ConstraintLayout. Это макет по умолчанию для шаблона Empty Activity.
  2. Добавьте TextView из палитры компонентов. Этот TextView будет использовано для отображения заголовка вверху экрана.
  3. Ограничение верхнего края TextView установим по верхней границе окна, левый край по левой стороне, а правый край по правой стороне экрана. Нижний край не ограничиваем.
  4. Установите значение ширину match_parent, а высоту wrap_content, поэтому высота изменится в соответствии с высотой содержимого.
  5. Установите идентификатор @+id/textview_label.
  6. Установите верхний, левый и правый отступ 24dp. Левый и правый отступы могут также иметь значение «start» и «end» для поддержки локализации языков с написанием справа налево.
  7. Установите значение параметра цвета текста @color/colorPrimaryDark и размер текста 24sp.
  8. Поместите текст в TextView «Это случайное число между 0 и %1d.» Спецификатор %1dбудет заменен числом в процессе работы приложения.
  9. Поместите текст в ресурсы с именем random_heading.

Это код XML для TextView, которое отображает заголовок:

Добавьте TextView для отображения случайного числа

  1. Добавьте TextView для отображения случайного числа.
  2. Установите значения параметров высоты и ширины wrap_content.
  3. Этот TextView будет находиться ниже TextView заголовка. Ограничьте верхний край по нижнему краю TextView заголовка. Остальные ограничения установите по остальным сторонам экрана.
  4. Установите идентификатор @+id/textview_random.
  5. Установите значение верхнего, леаого и правого отступов 24dp.
  6. Установите значение параметров textColor в @android:color/white, textSize в 72sp, и textStyle в bold.
  7. Напишите букву R в текстовом поле. Этот текст является просто заменителем, пока не будет сгенерировано случайное число.
  8. Установите значение параметра layout_constraintVertical_bias в 0.45.Этот TextView имеет ограничения по всем краям, так что лучше использовать вертикальные смещения, чем отступы для регулировки вертикального положения, чтобы макет одинаково хорошо выглядел в разных ориентациях и размерах экрана.

Это код XML для TextView которое отображает случайный номер:

Изменение цвета фона макета

Установите новому активити новый цвет фона, отличающийся от первого:

2. В макете для второго активити, установите элементу ConstraintLayout новый цвет. Это можно сделать в панели свойств или в коде XML:

Макет для второго активити готов. Вы можете посмотреть его на вкладке Дизайн.

Теперь пришло время реализовать переход на второй экран.

Запуск второго активити

Выполните такие шаги:

  1. Откройте класс MainActivity.kt.
  2. Добавьте метод randomMe(), который будет вызываться, когда нажата кнопка Random.Если вы забыли, как реализовать такой метод, посмотрите на код методов toastMe() и countMe().
  3. Добавьте код для запуска второго активити в тело метода randomMe():

4. Что еще нужно сделать, чтобы связать метод randomMe() с кнопкой Random? Сделайте это самостоятельно. Ищите подсказки в прошлом уроке.

Передача информации между активити

На втором экране при открытии должно отображаться случайное число из диапазона от нуля до текущего значения счетчика на первом экране. Для этого второму активити требуется текущее значение счетчика. Мы можем передать эту информацию в интенте, используя метод putExtra(). Второе активити может получить интент, который запустил его, и извлечь данные Extra Data из этого интента.

Обновите MainActivity для передачи дополнительных данных второму активити

  1. В классе SecondActivity.kt, объявите статическую переменную TOTAL_COUNT, для использования ее в качестве ключа для Extra Data.

2. Изменим метод randomMe(). Сначала получим текущее значение счетчика из TextView. Конвертируем значение в тип int, затем с помощью метода putExtra() добавим значение в Intent. Метод putExtra() принимает ключ и значение; в качестве ключа укажем константу TOTAL_COUNT из SecondActivity.kt.

Вот полный код метода randomMe():

Обновите SecondActivity для вычисления и отображения случайного числа

Мы написали код для отправки текущего значения счетчика во второе активити. На следующем шаге настроим SecondActivity.kt для получения и использования значения счетчика.

Напишем метод для извлечения значения счетчика и вычисления на его основе случайного числа

  1. В классе SecondActivity.kt, добавим метод showRandomNumber() без аргументов.
  2. Пропишем в этом методе генерацию и отображение случайного числа, максимальное значение которого соответствует значению счетчика.
  3. Используем метод getIntent() для получения интента, запустившего это активити. Используем метод getIntExtra() для получения extra data из интента; аргументами являются ключ или значение по умолчанию при его отсутствии.

Внимание: при получении данных из интента, вы должны знать их тип. Используйте соответствующий getter метод, например getStringExtra() или getIntExtra().

Полный код метода showRandomNumber():

Обновите метод onCreate()

Метод onCreate() вызывается при старте активити. Текущий метод onCreate() для SecondActivity устанавливает макет разметки для экрана. Добавим вызов метода showRandomNumber() в метод onCreate(), он будет обновлять текстовое поле для отображения случайного числа.

  1. Изменим метод onCreate() в SecondActivity. Добавим в конце вызов метода showRandomNumber().

2. Запустим приложение. Нажмем кнопку счетчика на некоторое время, затем нажмем кнопку Random button. В новом окне должно отобразиться случайное число.


На этом наш урок подошел к концу. Исходный код урока вы можете скачать по ссылке. Вопросы можно задавать в комментариях.

Чтобы ответить на событие нажатия кнопки, откройте fragment_main.xml файла макета и добавьте android:onClick атрибут к элементу:

android:onClick значение атрибута, "sendMessage" , это имя метода в вашей активити , который система вызывает когда пользователь нажимает кнопку.

Откройте MainActivity класс (расположенный в каталоге проекта src/ ) и добавьте соответствующий метод:

Чтобы система смогла найти этот метод с именем, заданным в android:onClick , сигнатура должна быть именно такой, как вы видели. В частности, метод должен:

  • Быть public
  • Имейте void в качестве возвращаемого значения
  • Иметь View в качестве единственного параметра (это будет View , на котором нажали)

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

Создать Intent

Intent это объект, который обеспечивает связывание отдельных компонент во время выполнения (например, двух активити ). Intent представляет «намерение что-то сделать». Вы можете использовать интент для широкого круга задач, но чаще всего они используются, чтобы начать другую активити .

Внутри sendMessage() метода, создайте Intent для запуска активити под названием DisplayMessageActivity :

Для этого требуется импортировать Intent класс:

Полезный совет: В Eclipse, нажмите Ctrl + Shift + O для импортирования недостающих классов (Cmd + Shift + O на Mac). В Android Studio команда для импорта Alt+Enter.

Конструктор, используемый здесь принимает два параметра:

  • Context в качестве первого параметра( this используется, поскольку Activity класс является подклассом Context )
  • Class компонента приложения, в который система должна доставить Intent (в данном случае активность, которая должна быть запущена)

Отправка intent в другие приложения

Примечание: Ссылка на DisplayMessageActivity вызовет ошибку, если вы используете интегрированную среду разработки, такую как Eclipse например, потому что класс еще не существует. Игнорируйте ошибку на данный момент; вы скоро создадите класс.

Intent не только позволяет начать другую Activity, но также может выполнять связь данных в Activity. В sendMessage() методе, используйте findViewById() для получения EditText элемента и добавьте его текстовое значение в Intent:

Примечание: Вам необходим оператор импорта для android.widget.EditText . Вы определите EXTRA_MESSAGE константу буквально сейчас.

Intent может нести коллекцию различных типов данных в виде пары ключ-значение, называемых Extras. Метод putExtra() принимает имя ключа в первом параметре и значение во втором параметре.

Для того, чтобы Activity смогла запросить дополнительные данные, вы должны определить ключ для дополнений вашего интента, используя общедоступную константу. Так что добавьте EXTRA_MESSAGE определение в начало MainActivity класса:

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

Запуск второй Activity

Для запуска активити, вызовите startActivity() и передайте в него ваш Intent . Система получает этот вызов и запускает экземпляр Activity указанный в Intent .

Теперь вам нужно создать DisplayMessageActivity класс для того, чтобы это работало.

Создание второй Activity

Для создания новой Activity в Android Studio:

В главном меню выберите File>New>Activity>Blank Activity.

Заполните поля в окне мастера создания активити:

Остальные поля оставьте по умолчанию. Нажмите Finish.

Для создания новой Activity в Eclipse:

Рисунок 1. Мастер новой активити в Eclipse.

Если вы используете инструменты командной строки, создайте новый файл с именем DisplayMessageActivity.java в проекте в src/ каталоге, рядом с оригиналом MainActivity.java файлом.

Откройте DisplayMessageActivity.java файл. Если вы использовали Android Studio или Eclipse для создания этой Activity:

  • Класс уже включает в себя реализацию требуемого onCreate() метода. Вы обновите реализацию этого метода позже.
  • Есть также реализация onCreateOptionsMenu() метода, но вам это не будет нужно в данном приложении, так что вы можете удалить его.
  • Есть также реализация onOptionsItemSelected() , который обрабатывает поведение панели действий для кнопки Вверх . Оставьте его как есть.
  • Может быть также PlaceholderFragment класс, который расширяет Fragment . Вам не нужен будет этот класс в окончательном варианте этой активити .

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

Примечание: Ваша активити может выглядеть иначе, если вы не использовали последнюю версию ADT плагина. Убедитесь, что вы установили последнюю версию ADT плагина для завершения этого курса.

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

Если вы использовали среду разработки, отличную от Android Studio или Eclipse, обновите ваш DisplayMessageActivity класс согласно коду приведенного выше.

Все подклассы Activity должны реализовать onCreate() метод. Система вызывает его при создании нового экземпляра активити . В этом методе вы должны определить макет активити с помощью setContentView() метода, и здесь вы должны выполнить начальную настройку компонентов активити .

Примечание: Если вы используете среду разработки, отличную от Android Studio или Eclipse, ваш проект не содержит activity_display_message макет, который необходим для setContentView() . Всё в порядке, потому что вы будете обновлять этот метод позже и не будете использовать этот макет.

Добавить строку заголовка

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

Иначе, добавьте заголовок для новой активити в strings.xml файл:

Добавьте её в манифест

Все Activity должны быть объявлены в файле манифеста, AndroidManifest.xml , c использованием тега .

При использовании Android Studio или Eclipse для создания своей Activity, запись в манифесте создается по умолчанию. В других случаях можно добавить запись в манифест самим. Это должно выглядеть следующим образом:

Атрибут android:parentActivityName объявляет имя родительской Activity в рамках логической иерархии приложения. Система использует это значение для реализации поведения навигации по умолчанию, такого как навигация Вверх на Android 4.1 (Уровень API 16) и выше. Вы можете реализовать такое же поведение навигации для более старых версий Android, используя Библиотеку Поддержки и добавив элемент, как показано здесь.

Примечание: Ваш Android SDK уже должен включать последнюю версию Библиотеки Поддержки Android. Он включен в пакет ADT, но если вы используете другой IDE, он должен был быть установлен на шаге Добавление платформ и пакетов . В Android Studio и Eclipse, Библиотека Поддержка автоматически добавляется в ваше приложение проекта (вы можете увидеть JAR файл библиотеки, перечисленный в Зависимости Android). Если вы не используете Eclipse, вам нужно вручную добавить библиотеку в проект — следуйте инструкциям в руководстве настройка библиотеки поддержки , а затем вернитесь сюда.

Получение Интента

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

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


Рисунок 2. Две активити в законченном приложении, работающие на Android 4.4.

Вот и все, вы создали своё первое Android приложение!

Чтобы узнать больше, перейдите по ссылке на следующий курс.

Следующий курс: Поддержка различных Android устройств

Если не указано иное, этот контент распространяется под лицензией Creative Commons Attribution 2.5. Для получения дополнительной информации и ограничений, см. Лицензия контента.

Now in Android

Ответ на вопрос Макса Сергеева (лучше поздно чем никогда? ) ), переход по стрелочке назад организовывается через указание родительской связи при создании нового активити, либо вручную при добавлении свойства «android:parentActivityName» у соответствующего активити в AndroidManifest.xml


Интересно тут вот что.
Если мы возвращаемся назад на предыдущее активити стрелкой в шапке, то оно уничтожается и создаётся заново .
«Activity 2 create!
onStart — Activity 2 становится видимым!
onResume — Activity 2 получает фокус!
onStop — Main Activity остановлено!
onPause — Activity 2 приостановлено!
Activity 3 create!
onStart — Activity 3 становится видимым!
onResume — Activity 3 получает фокус!
onStop — Activity 2 остановлено!
onPause — Activity 3 приостановлено!
onDestroy — Activity 2 уничтожено!
Activity 2 create!
onStart — Activity 2 становится видимым!
onResume — Activity 2 получает фокус!
onStop — Activity 3 остановлено!
onDestroy — Activity 3 уничтожено!»

А если мы возвращаемся через кнопку назад на телефоне то оно восстанавливается.
«onPause — Activity 2 приостановлено!
Activity 3 create!
onStart — Activity 3 становится видимым!
onResume — Activity 3 получает фокус!
onStop — Activity 2 остановлено!
onPause — Activity 3 приостановлено!
onRestart — Activity 2 перезапускается!
onStart — Activity 2 становится видимым!
onResume — Activity 2 получает фокус!
onStop — Activity 3 остановлено!
onDestroy — Activity 3 уничтожено!»

Хотя может быть это всем известная вещь и я ещё не дошел до той лекции где это описывается.

В прошлых темах мы рассмотрели жизненный цикл activity и запуск новых activity с помощью объекта Intent. Теперь рассмотрим некоторые особенности взаимодействия между activity в одном приложении. Допустим, у нас есть три activity: MainActivity, SecondActivity и ThirdActivity.

Back stak и управление стеком из Activity в Android и Java

С помощью Intent, например, по нажатию кнопки MainActivity запускает SecondActivity:

На SecondActivity тоже есть кнопка, которая запускает ThirdActivity:

На ThirdActivity также есть кнопка, которая возвращается к первой activity - MainActivity:

Взаимодействие между Activity в Android и Java

Если мы последовательно запустим все activity: из главной MainActivity запустим SecondActivity, из SecondActivity - ThirdActivity, то в итоге у нас сложится следующий стек activity:

ThirdActivity
SecondActivity
MainActivity

Если после этого из ThirdActivity мы захотим обратиться к MainActivity, то метод startActivity() запустит новый объект MainActivity (а не вернется к уже существующему), и стек уже будет выглядеть следующим образом:

MainActivity
ThirdActivity
SecondActivity
MainActivity

То есть у нас будут две независимые копии MainActivity. Такое положение нежелательно, если мы просто хотим перейти к существующей. И этот момент надо учитывать.

ThirdActivity
SecondActivity
MainActivity

Тем не менее иногда возникает необходимость упавлять переходом между activity. Например, в данном случае нам нежелательно при нажатии на кнопку в ThirdActivity запускать новую копию MainActivity вместо того, чтобы просто перейти к MainActivity, которая была запущена первой и находится в самом низу стека. Рассмотрим, какие возможности предоставляет нам Android.

Управление стеком activity

Для управления стеком из activity Android предлагает нам использовать флаги - константы, определенные в классе Intent . Применение определенного флага позволит нам определенным образом изменить положение в стеке для определенных activity.

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

MainActivity
ThirdActivity
SecondActivity
MainActivity

Чтобы выйти из этой ситуации, мы можем использовать флаг Intent.FLAG_ACTIVITY_REORDER_TO_FRONT :

флаг Intent.FLAG_ACTIVITY_REORDER_TO_FRONT перемещает activity, к которой осуществляется переход на вершину стека, если она ужее есть в стеке. И в этом случае после перехода из ThirdActivity к MainActivity стек будет выглядеть следующим образом:

MainActivity
ThirdActivity
SecondActivity

Если же нам просто надо перейти из ThirdActivity к MainActivity, как если бы мы перешли назад с помощью кнопки Back, то мы можем использовать флаги Intent.FLAG_ACTIVITY_CLEAR_TOP и Intent.FLAG_ACTIVITY_SINGLE_TOP :

Флаг Intent.FLAG_ACTIVITY_CLEAR_TOP очищает все activity кроме той, которая запускается (если она уже есть в стеке). А флаг Intent.FLAG_ACTIVITY_SINGLE_TOP указывает, что если в вершине стеке уже есть activity, которую надо запустить, то она НЕ запускается (то она может существовать в стеке только в единичном виде).

В этом случае после перехода из ThirdActivity к MainActivity стек будет полностью очищен, и там останется одна MainActivity.

Еще один флаг - Intent.FLAG_ACTIVITY_NO_HISTORY позволит не сохранять в стеке запускаемую activity. Например, при запуске SecondActivity мы не хотим ее сохранять в стеке:

В этом случае при переходе по цепочке MainActivity -> SecondActivity -> ThirdActivity стек будет выглядеть следующим образом:

Читайте также: