Android обмен данными между фрагментами

Русские Блоги

Три способа передачи данных между фрагментами Android

Android] Три способа передачи данных между фрагментами

I. Введение

В процессе разработки Android мы знаем важность Activity, но начиная с android3.0, фрагмент, который появляется в android, на самом деле не менее важен, чем Activity. Сегодня я кратко расскажу о трех способах передачи данных между фрагментами.

Во-вторых, подготовить к работе

Шаг 1: Создайте Activity с именем MainActivity. Соответствующий файл макета выглядит следующим образом (перехватывается только основная часть):

Шаг 2: Создайте два фрагмента, MenuFragment и MainFragment. Соответствующий макет выглядит следующим образом:
Основная структура MenuFragment:

Основная структура основного фрагмента:

шаг 3: каждый из двух фрагментов представляет макет (в методе onCreateView ()) (для конкретного кода обращайтесь к исходному коду). Следует отметить, что MenuFragment является ListView. Здесь 5 данных добавляются вручную для заполнения;
step4: введите эти два фрагмента в метод onCreate () MainActivity:

Отображаемый интерфейс выглядит следующим образом:

Вышеуказанные приготовления завершены!

Соответствующие операции трех методов передачи данных

спрос: Мы щелкаем соответствующие данные записи, показанные на рисунке выше, и заменяем текстовые данные, соответствующие правой (желтая кнопка), текстом, отображаемым записью. Например: я щелкаю четвертую запись слева, и текст на правой кнопке меняется на » Это четвертый кусок данных », чтобы добиться передачи данных между фрагментами. Далее описаны три способа достижения передачи данных между фрагментами.

  • 1. Установите метод setData () в MainFragment и установите имя кнопки изменения в методе;
  • 2. Получите MainFragment через метку в событии щелчка элемента ListView в MenuFragment и вызовите соответствующий метод setData (), чтобы установить данные для достижения цели передачи данных.

Всего двумя шагами выше можно достичь цели передачи данных.

Способ второй
Данные передаются через обратный вызов интерфейса.

  • Шаг 1: Создайте интерфейс и установите метод, соответствующий интерфейсу в Menuragment:
  • Шаг 2. Выполните обратный вызов интерфейса в событии щелчка элемента ListView в MenuFragment.
  • Шаг 3: Получить метод set интерфейса в соответствии с menuFragment в MainActivity и выполнить передачу данных в этом методе следующим образом:

С помощью трех вышеперечисленных шагов вы также можете легко передавать данные фрагмента.

Способ третий
использует трехстороннюю среду с открытым исходным кодом:EventBus
Тогда возникает вопрос: что такое EventBus? ? ?
Проще говоря,EventBusШина событий публикации / подписки, оптимизированная для Android. Основная функция — заменить Intent, Handler, BroadCast для передачи сообщений между Fragment, Activity, Service и потоком. Упрощенная связь между компонентами в приложении, между компонентами и фоновыми потоками.Преимуществами являются меньшие издержки, более элегантный код и разделение отправителя и получателя.Например, запросите сеть и уведомите пользовательский интерфейс через обработчик или широковещательную рассылку, когда сеть вернется. Два фрагмента должны обмениваться данными через прослушиватель. Эти требования могут быть выполненыEventBusДля достижения.
Теперь мы используем EventBus для передачи данных между следующими фрагментами:

  • Шаг 1: Представляем EventBus
  • Шаг 2: Зарегистрировать получатель события
    Здесь MainFragment предназначен для получения данных, отправленных MenuFragment, поэтому мы регистрируемся в методе onCreateView () в MainFragment:
  • Шаг 3: Отправить событие
    Примечание:На самом деле существует шаг для определения типа события перед отправкой события, здесь мы передаем только один тип данных, поэтому этот шаг отменяется.
    MenuFragment отправляет данные в MainFragment, поэтому мы отправим данные для передачи в MenuFragment для операции события:
  • шаг 4: получение сообщений и обработка
    В MainFragment мы получаем данные, переданные из MenuFragment, и выполняем соответствующую обработку (Примечание. На этом шаге версии EventBus 3.0 необходимо написать аннотацию @Subscribe (отличается от версии 2.4)) :
Читайте также:  Мстители тема для андроид

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

  • шаг 5: прием события выхода из системы

Вышеприведенные пять шагов завершили передачу данных между фрагментами, что представляется более сложным, чем два вышеупомянутых метода, но когда мы включаем сложную передачу данных между фрагментами (например, вложение нескольких фрагментов во фрагменты), мы будем Испытайте свежесть EventBus

Источник

Доступ к View внутри фрагмента

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

Доступ к View внутри динамического фрагмента из активности

Рассмотрим пример доступа к компоненту, который находится внутри динамического фрагмента из активности.

Фрагмент может иметь собственную разметку и содержать различные компоненты View: TextView, EditText и т.д. Напрямую из активности обратиться к нужному компоненту и поменять, например, текст в TextView не получится. А как же достучаться до нужного компонента? Рассмотрим простой пример.

Создадим класс фрагмента MyFragment.java:

В методе onCreateView() мы указали ресурс разметки R.layout.fragmentlayout. Давайте создадим разметку для фрагмента.

res/layout/fragmentlayout.xml

В данной разметке нас интересует вторая текстовая метка с идентификатором fragmenttext.

Создадим разметку для основной активности:

Последняя компоновка LinearLayout с идентификатором myfragment является контейнером для фрагмента, который будет его замещать. Напишем код для главной активности:

При запуске программы мы получаем экземпляр класса FragmentTransaction и добавляем фрагмент на экран вместо LinearLayout. Теперь текстовая метка фрагмента доступна для изменения — получаем ссылку на нужный компонент и устанавливаем требуемый текст.

Передача данных между фрагментами

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

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

Читайте также:  Android editable set text

res/layout/redfragment.xml

res/layout/bluefragment.xml

В код первого фрагмента добавим только наполнение из разметки:

В класс второго фрагмента добавим код для чтения данных из первого фрагмента. Сделаем это в методе onStart():

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

Источник

Урок 15. Передача данных между экранами — пунктами назначения. Android Navigation. Bundle vs Safe Args

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

На прошлом уроке мы выполняли навигацию по условию, авторизован пользователь или нет.

На этом уроке

На этом уроке рассмотрим возможности передачи данных между экранами – пунктами назначения навигации в андроид-приложении. Создадим приложение с двумя экранами. На первом экране будет поле для ввода имени и кнопка отправки, а на втором экране будет отображаться приветствие с именем, которое мы указали. Таким образом, мы передадим данные (имя) с первого экрана на второй.

Передача данных между экранами

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

Bundle или Safe Args?

В этом уроке мы рассмотрим два способа передачи данных между фрагментами: традиционный – с помощью наборов данных Bundle и типобезопасный – при помощи безопасных аргументов SafeArgs. Первый способ относительно прост – создаем набор данных «ключ-значение» типа Bundle и передаем через action в первом фрагменте, и извлекаем во втором фрагменте.
Второй способ потребует немного больше кода. На первый взгляд он может показаться сложнее, поскольку используется кодогенерация – среда разработки создает необходимые классы вместо вас. Но мы попробуем разобраться и вы увидите, что ничего особо сложного там нет. По сути, SafeArgs – просто обертка над Bundle. Тем не менее, разработчики настоятельно рекомендуют применять именно SafeArgs, как типобезопасный способ передачи данных между фрагментами в процессе навигации.

Создаем проект

Откройте среду разработки Android Studio и создайте новый проект с использованием шаблона Empty Activity.

Создаем граф навигации

Далее перейдите в папку res и создайте в ней папку navigation. Внутри папки navigation создайте Navigation Resource File с именем nav_graph.xml и корневым элементом .

Если вы забыли добавить в проект необходимые для поддержки навигации библиотеки – Android Studio предложит это сделать за вас, показав предупреждение.

Добавляем пункты назначения – фрагменты

Добавьте новые пункты назначения. Для этого:

  1. В окне редактора дизайна нажмите кнопку «New destination»
  2. Выберите «Create new destination»
  3. Далее в окне добавления фрагмента выберите Fragment (Blank):

Источник

Android Fragment Result Listener

В Android передача данных между фрагментами может осуществляться разными способами: передача через родительскую Activity, используя ViewModel или даже Fragments API. Fragment Target API с недавних пор получил статус Deprecated и вместо него Google рекомендует использовать Fragment result API.

Что такое Fragment result API? Это новый инструмент от Google который позволяет передавать данные между фрагментами по ключу. Для этого используется FragmentManager, который в свою очередь реализует интерфейс FragmentResultOwner. FragmentResultOwner выступает в качестве центрального хранилища для данных, которые мы передаем между фрагментами.

Читайте также:  Джек лондон для андроид

Как это работает?

Как упоминалось выше, наш FragmentManager реализует интерфейс FragmentResultOwner, который хранит в себе ConcurrentHashMap . Эта HashMap хранит наши Bundle-ы по строковому ключу. Как только один из фрагментов подписывается (или уже подписан) то он получает результат по тому самому ключу.

Что важно знать:

  • Если какой-либо фрагмент подписывается на результат методом setResultFragmentListener() после того, как отправляющий фрагмент вызовет setFragmentResult() , то он немедленно получит результат
  • Каждую связку “Key + Result (Bundle)“ фрагмент получает только 1 раз
  • Фрагменты которые находятся в бек стеке получат результат только после того как перейдут в состояние STARTED
  • После того как фрагмент перейдет в состояние DESTROYED мы больше не сможем подписываться на ResultListener

Как это выглядит в коде?

Передача данных

Для передачи данных в другой фрагмент нам необходимо вызвать метод:

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

Получение данных

Для получения данных через FragmentManager мы регистрируем наш FragmentResultListener и задаем ключ по которому мы будем получать данные. Тот самый ключ который мы указывали в методе FragmentManager.setFragmentResult()

Здесь мы видим 2 аргумента: key: String и bundle: Bundle.
Первый — это тот самый ключ, по которому мы передаем сюда данные. Второй — Bundle, в котором лежат переданные данные.

Parent Fragment Manger

Выбор FragmentManager-а для передачи данных между фрагментами зависит от принимающего фрагмента:

  • Если оба фрагмента находятся в одном и том же FragmentManager (например оба фрагмента находятся в Activity), то мы должны использовать родительский FragmentManager, который хранит в себе Activity
  • Если у нас один фрагмент вложен в другой фрагмент, то для передачи данных мы используем childFragmentManager (он же родительский фрагмент для принимающего фрагмента)

Важно понимать, что наш FragmentResultListener должен находиться в общем для двух фрагментов FragmentManager-е.

Тестирование

Для тестирования отправки/получения данных через FragmentResultListener, мы можем использовать FragmentScenario API, который предоставляет нам все преимущества тестирования фрагментов в изоляции.

Передача данных

Как мы можем протестировать, что наш фрагмент корректно отправляет данные через родительский FragmentManager? Для этого нам необходимо внутри теста отправить результат и проверить, что наш FragmentResultListener получил корректные данные:

Получение данных

Для проверки корректности получения данных мы можем симулировать отправку данных, используя родительский FragmentManager. Если в отправляющем фрагменте корректно установлен FragmentResultListener мы должны получить корректные данные проверяя сам листенер или последствие их получения.

Вывод

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

Для того чтоб получить возможность использовать FragmentResultListener нам нужно подключить в зависимостях версию фрагментов 1.3.0-alpha04 или новее:

Источник

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