Android java viewpager2 fragments передача данных

Перелистывание страниц и ViewPager2

ViewPager2 и разделение приложения на страницы

Нередко можно встретить приложения, которые реализуют систему перелистывания, а само приложение предстает в виде набора страниц, которые можно пролистывать влево и вправо. В приложении Android для создания подобного эффекта можно использовать элемент ViewPager2 из комплекта JetPack. Для создания эффекта страниц ViewPager2 использует фрагменты.

Итак, создадим новый проект. Добавим в папку res/layout файл разметки для фрагмента, который будет представлять страницу. Назовем его fragment_page.xml и определим в нем следующий код:

Фрагмент будет отображать текстовое поле с номером страницы.

Теперь добавим в проект сам класс фрагмента. Назовем его PageFragment :

Переменная pageNumber указывает на номер текущей страницы. Номер страницы будет передаваться извне через фабричный метод newInstance() . Передача номера происходит путем добавления значения в аргумент «num»

Затем при создании фрагмента в методе onCreate() этот номер будет извлекаться из аргумента «num» (если аргументы определены):

В методе onCreateView() полученный номер страницы будет отображаться в текстовом поле.

Сам по себе фрагмент еще не создает функциональность постраничной навигации. Для этого нам нужен один из классов PagerAdapter . Android SDK содержит ряд встроенных реализаций PagerAdapter, в частности, класс FragmentStateAdapter . Этот класс являются абстрактным, поэтому напрямую мы его использовать не можем, и нам нужно создать класс-наследник. Для этого добавим в проект новый класс, который назовем MyAdapter :

Класс FragmentStateAdapter определяет два метода:

int getItemCount() : возвращает количество страниц, которые будут в ViewPager2 (в нашем случае 10)

Fragment createFragment(int position) : по номеру страницы, передаваемому в качестве параметра position, возвращает объект фрагмента

Стоит отметить, что в качестве параметра конструктор FragmentStateAdapter принимает контекст выполнения — обычно это объект FragmentActivity, но также это может быть объект Fragment

В завершении установим в файле activity_main.xml элемент ViewPager2:

И также изменим код MainActivity :

Класс MainActivity наследуется от AppCompatActivity — класса, который в свою очередь наследуется от FragmentActivity, и поэтому ее текущий объект мы можем передать в качестве параметра в конструктор MyAdapter (а через него — в конструктор FragmentStateAdapter). Чтобы перелистывание заработало, для ViewPager2 устанавливается адаптер MyAdapter.

И запустив проект, мы сможем с помощью перелистывания перемещаться по страницам:

Источник

Как работать с ViewPager2

Прошло не так много времени с тех пор, как 7 февраля 2019 года Google выпустила альфа-версию Android ViewPager2. Более подробную информацию об этом релизе можно найти здесь. А сейчас давайте посмотрим, что из себя представляет ViewPager2.

Новые фичи

Что изменилось?

ViewPager2 выпущен для Android X, поэтому, если вы хотите его использовать, ваш проект должен использовать Android X. Давайте посмотрим, как мы можем использовать этот новый ViewPager2.

Добавление зависимости

Добавьте следующую зависимость в файл build.gradle на уровне приложения:

Читайте также:  Android внешняя клавиатура переключение раскладки android

После этого синхронизируйте свой проект.

Настройка

Добавьте виджет ViewPager2 в вашу Activity или фрагмент:

Давайте создадим layout для страницы, которая будет отображаться во ViewPager2:

Далее нам нужно создать Adapter для ViewPager2. Это самая интересное. Для этого мы можем использовать RecyclerView.Adapter . Разве это не круто?

Это такой же адаптер, который мы используем для обычного RecyclerView, и с ViewPager2 он работает так же хорошо.

Последний шаг, установим адаптер для ViewPager2:

Вот и всё! Получаем тот же результат, как и при использовании старого ViewPager с PagerAdapter:

Вертикальная прокрутка

Раньше нужно было использовать сторонние библиотеки для реализации вертикальной прокрутки, т.к. до сих пор Google не предоставляла такой возможности «из коробки». В этом новом ViewPager2 теперь есть поддержка вертикальной прокрутки. Просто измените ориентацию во ViewPager2 и вертикальная прокрутка будет включена. Очень просто!

Вот, что получается в итоге:

Использование FragmentStateAdapter

Вы также можете использовать фрагменты в качестве страниц, как и в старом ViewPager. Для этого есть FragmentStateAdapter. Давайте посмотрим, как мы можем его использовать.

Прежде всего, нам нужно создать фрагмент:

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

Теперь установим этот новый адаптер во ViewPager2, и всё готово:

Улучшенный OnPageChangeCallback

В старом ViewPager интерфейс OnPageChangeListner был предназначен для получения событий изменения/прокрутки страницы. И это была очень неудобно, т.к. нам нужно было переопределять все три метода ( onPageScrollStateChanged , onPageScrolled , onPageSelected ), даже если мы этого не хотели.

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

Внимание!

Поскольку ViewPager2 находится в альфа-версии, есть некоторые функции старого ViewPager, которые ещё не были реализованы или не работают должным образом в этой версии.

Известные проблемы согласно документации:

  • ClipToPadding,
  • Отсутствует интеграция с TabLayout,
  • Отсутствует контроль за пределами экрана,
  • Нельзя установить ширину страницы (100% по умолчанию)

Больше информации об известных проблемах — здесь. Надеюсь, что всё это будет исправлено в ближайших обновлениях. Я с нетерпением жду стабильной версии этого нового ViewPager2. А до тех пор, хорошего всем кода!

Источник

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 или новее:

Источник

ViewPager2 with Fragments Android Example

In this post, I’ll learn viewpager2 with fragments implementation in Android. ViewPager2 is an optimized version of ViewPager. In the previous article, I was explained the implementation of ViewPager2 with TabLayout Android.

Internally ViewPager2 uses RecyclerView component to display swipeable content. ViewPager2 have so many new features, In this android example post, we’ll learn ViewPager2 implementation with Fragments.

Steps of Implementation ViewPager2 with Fragments
  • Create a project with androidx
  • Add the ViewPager2 dependencies
  • Update some resource file, that needed for this demo
  • Create fragments for ViewPager2
  • Create a subclass of FragmentStateAdapter
  • Add the ViewPager in activity layout
  • Finally set the FragmentStateAdapter on ViewPager
Читайте также:  Как повысить работу андроида
1. Create a project with Androidx

Let’s open the Android Studio to create a project with AndroidX.

2. Add the ViewPager2 dependencies

Open the app-level build. gradle file and add below dependencies

3. Update some resource file

Add few color items in color.xml files

4. Create fragments for ViewPager2

Simply creates a fragment named is CardFragment with XML layout. Open the layout file paste below code.

Bind above fragment layout with file

Let’s paste below code in the CardFragment.java file. In this fragment have a TextView

5. Create a subclass of FragmentStateAdapter
6. Add the ViewPager in activity layout
7. Finally set the FragmentStateAdapter on ViewPager

Conclusion

In this android app example, we have learned the implementation of ViewPager2 with Fragment in Android. I hope it’s helpful for you.

Keep in touch

If you want to keep in touch and get an email when I write new blog posts, follow me on facebook or subscribe to us. It only takes about 10 seconds to register.

Источник

Передача данных через фрагменты в viewpager

У меня есть Viewpager с 2 фрагментами: CurrentWeatherFragment и ForecastFragment . Мне нужно передать строку из одного в другой, используя интерфейс, как показано ниже, но я продолжаю получать NullPointerException , сообщение не проходит должным образом …

Я успешно использовал этот метод в другом приложении, где у меня было 2 фрагмента в одном действии, и я мог назвать их по ID

Но здесь Fragments не имеет идентификаторов, и я думаю, что это сообщение не передается, потому что я не использую FragmentManager() , но как найти фрагмент в viewpager без ID, любые предложения / идеи?

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

Где R.id.pager является идентификатором viewpager в вашем макете, а index – это позиция (как целое) в адаптере Viewpager. Я не могу сказать, что это будет работать вечно, но сейчас это работает для меня.

Альтернатива, которую я предлагаю, заключается в использовании LocalBroadcastManager и BroadcastReciver для отправки данных между вашими фрагментами, так как, хотя его немного больше работы, он помогает избавиться от ситуации с кодом спагетти, вы можете оказаться в попытке напрямую ссылаться на фрагменты.

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

Имейте в виду, что не переопределяйте конструктор по умолчанию, вместо этого создайте статический метод getInstance (данные String).

Затем вы можете получить данные в методе onCreate фрагмента с помощью метода getArguments ()

Для некоторых других пользователей, таких как я, которые ищут фрагмент для отправки данных viewpager

Вот рабочее решение:

Отправка данных из фрагментов фрагмента фрагмента фрагмента страницы:

В главном фрагменте:

Для компоновки вкладок я использую два фрагмента

1) BillDetailFragment и

И вот как получить доступ к этим данным из фрагмента

BillDetailFragment: переопределить метод onCreate

Источник

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