- Android working with ViewPager2, TabLayout and Page Transformers
- Whats’s New in ViewPager2
- 1. ViewPager with Static Views
- 2. ViewPager with Tabs & Fragments
- 3. ViewPager2 Orientation
- 4. ViewPager Transformers
- Android TabLayout example using ViewPager2 and Fragments with Latest android API AndroidX
- Android — ViewPager2 — заменяем фрагменты на лету (программно)
- Задача
- Результат
- Дисклеймер (не читать, вода)
- Решение
- Верстка
- Интерфейсы
- Связь активити и ViewPager2
- Адаптер для ViewPager2 — всё здесь
- Пример использования
- Мысли в слух
- Русские Блоги
- Использование ViewPager2
- Справочник статей
- Введение
- Простое понимание исходного кода
- Изменить точку
- Обычно используемые API
- Внедрить реализацию
- Официальная демонстрация
- ViewPager2 with Views
- ViewPager2 with Fragments
- ViewPager2 with TabLayout
- ViewPager2 with PageTransformer
- ViewPager2 with MultiPages
- ViewPager2 with notifyDataSetChanged
- ViewPager2 with fake drag
- О offscreenPageLimit (предварительная загрузка)
Android working with ViewPager2, TabLayout and Page Transformers
As we all know, the Android team is constantly releasing new updates and improvements to the Android Framework. One of the components that received major updates is ViewPager2. ViewPager2 is the replacement of ViewPager and got few performance improvements and additional functionalities. In order to use ViewPager2, you should consider using androidx artifacts in your project.
In my earlier tutorial, I have explained Building Intro Sliders to your App using ViewPager. In this article, we are going to try the same but using ViewPager2. We’ll also go through the additional interesting functionalities provided by ViewPager2.
DEMO
Whats’s New in ViewPager2
- ViewPager2 is improvised version of ViewPager that provides additional functionalities and addresses common issues faced in ViewPager.
- ViewPager2 is built on top of RecyclerView. So you will have great advantages that a RecyclerView has. For example, you can take advantage of DiffUtils to efficiently calculate the difference between data sets and update the ViewPager with animations.
- ViewPager2 supports vertical orientation. Earlier vertical swiping is done by customizing the ViewPager.
- ViewPager2 has right-to-left(RTL) support and this will be enabled automatically based on app locale.
- When working with a collection of Fragments, calling notifyDatasetChanged() will update the UI properly when an underlying Fragment changes its UI.
- ViewPager2 supports page transformations i.e you can provide animations when switching between pages. You can also write your own custom page transformation.
- PagerAdapter is replaced by RecyclerView.Adapter as its based on RecyclerView.
- FragmentStatePagerAdapter is replaced by FragmentStateAdapter.
To get started with ViewPager2, add the dependency to app/build.gradle.
1. ViewPager with Static Views
Usually, ViewPager is used to achieve a tabbed view by combining the TabLayout and collection of Fragments. But if you want to have static views without the Fragment class, you can do it using RecyclerView adapter class.
Below is an example of implementing Intro Slides using ViewPager2. The designs are taken from my older example How to Build Intro Slider for your App but the implementation part varies due to changes in ViewPager2 and in adapter class.
Add the ViewPager2 to your layout file. You can see namespace is uses androidx package androidx.viewpager2.widget.ViewPager2.
This creates horizontally swipeable views that are created using static XML layouts. The full code of this example can be found here.
2. ViewPager with Tabs & Fragments
If you want to create swipeable views with Tabs, you can combine ViewPager2, TabLayout and Fragments.
To use TabLayout, add Material Components to your package. This makes the material TabLayout available in your project.
Add TabLayout and ViewPage2 to your layout.
Create required test Fragment classes MoviesFragment, EventsFragment and TicketsFragment.
Finally, create an adapter class that provides Fragments to ViewPager. Here we can see ViewPagerFragmentAdapter extends FragmentStateAdapter.
3. ViewPager2 Orientation
In a few scenarios, you might want to provide vertical swiping instead of traditional horizontal swiping. To enable vertical swiping, add android:orientation to ViewPager2 element.
Vertical orientation can also be enabled programmatically by calling setOrientation() method.
4. ViewPager Transformers
Another great feature of ViewPager2 is, page transformations i.e the page transition animation from one page to another. Traditionally, we see a sliding animation between two screens. This animation can be customized by providing page transformers to ViewPage2.
To set a custom transformation, use setPageTransformer() method. Below example creates Flip animation between pages.
This creates beautiful vertical flip animation when swiping the pages.
Below are a set of ViewPager transitions that I have collected from different sources (All the credits goes to original authors).
Hi there! I am Founder at androidhive and programming enthusiast. My skills includes Android, iOS, PHP, Ruby on Rails and lot more. If you have any idea that you would want me to develop? Let’s talk: [email protected]
Источник
Android TabLayout example using ViewPager2 and Fragments with Latest android API AndroidX
In this tutorial we are going to create 3 Tabs .Every tab have its own Fragment to control over screen. Also user can swipe between 3 tabs.
we are using AndroidX support Library , ViewPager2 and 3 different fragment & 3 different xml for layouts. And TabLayout for Tabs.
Layout Demonstration :
- Checkout the following pic which explains the complete overview of layout architecture. Basically we are using ViewPager as main layout and for individual pager views we use Fragments. The tabs are part of Action Bar.
STEP 1: CREATING PROJECT
- Let’s start with creating new project in android studio with package name com.example.manualSliding and class name MainActivity.java and its layout name is activity_main.xml.
STEP 2: ADDING DEPENDENCIES
- open file Gradle Scripts/build.gradle(Module: app)
- under dependencies add this:
- under compileOptions<> add this:
STEP 3: EDIT app/res/values/colors.xml
STEP 4: EDIT app/res/values/styles.xml : we using this theme because TabLayout component works in this theme.
STEP 6: CREATING LAYOUT FOR EACH FRAGMENT :
- create new xml layout file under app/res/layout/first_frag.xml and add the below code:
- create new xml layout file under app/res/layout/second_frag.xml and add the below code:
- create new xml layout file under app/res/layout/third_frag.xml and add the below code:
STEP 7: Create FRAGMENT CLASS for each view layout:
Источник
Android — ViewPager2 — заменяем фрагменты на лету (программно)
Вдруг вам надо листать фрагменты через ViewPager2 и при этом подменять их динамически. Например, чтобы уйти «глубже» — пользователь из фрагмента «Главные настройки» переходит во фрагмент «Выбор языка». При этом новый фрагмент должен отобразиться на месте главного фрагмента. А потом пользователь еще и захочет вернуться обратно.
список Fragment-ов (например, разделы анкеты или многостраничный раздел настроек)
Kotlin (Java), Android собственно
Задача
Необходимо заменять фрагменты динамически — на месте n-ого фрагмента должен появится другой. При этом все остальные страницы не должны терять своего состояния.
Есть три фрагмента. Первый — список любимых тарелок, второй — экран с сообщениями, третий — настройки.
Пользователь на первом экране выбирает тарелку -> меняем первый фрагмент на фрагмент «Информация о тарелке»
Пользователь листает свайпами или выбирает через TabLayout третий экран — «Настройки», выбирает раздел «Выбор языка» -> меняем третий фрагмент на фрагмент «Выбор языка»
Теперь пользователь, не выходя из выбора языка, листает до первого фрагмента. Он должен увидеть информацию о тарелке, а не список любимых тарелок.
Итак, пытаемся сдружить ArrayMap и ViewPager2.
Результат
Дисклеймер (не читать, вода)
Пишу, потому что найти хороших решений по этой задаче не смог, хотя вроде пытался усердно.
Код местами специально упрощен — не люблю, когда в статьях добавляют десятки строк, не касающихся решения описываемой задачи, только ради соблюдения всех правил. Так что: строковые ресурсы — вынести, вью модели для фрагментов — добавить, пару уровней абстракций — ну вы поняли
Весь проект — https://github.com/IDolgopolov/ViewPager2_FragmentReplacer
Иногда буду использовать слово «страницы» — имею ввиду позицию, на которой отображается фрагмент во ViewPager. Например, «Список любимых тарелок», «Экран сообщений» и «Настройки» — три страницы. Фрагмент «Выбор языка» заменяет третью страницу.
Решение
Сначала ничего интересного, просто для общего ознакомления
Верстка
Интерфейсы
Опишем функции, которые нам понадобятся для смены фрагментов
Все фрагменты, добавляемые во ViewPagerAdapter (MyViewPager2Adapter описан ниже), будут наследоваться от BaseFragment.
Определим в нем переменные для хранения:
pageId — уникальный номер страницы. Может быть любым числом, но главное — уникальным и большим, чем у вас позиций страниц (pageId > PAGE_COUNT — 1), иначе будут баги из-за метода getItemId()
pagePos — номер странице, на которой будет отображаться фрагмент во ViewPager (начиная с 0, естественно)
fragmentReplacer — ссылка на ViewPagerAdapter (MyViewPager2Adapter реализует FragmentReplacer)
Связь активити и ViewPager2
Адаптер для ViewPager2 — всё здесь
В этом классе будут реализован интерфейс FragmentReplacer и переопределены несколько классов FragmentStateAdapter. Это и позволит менять фрагменты на лету.
Весь код класса, который ниже разбираю подробно
В первую очередь переопределим четыре метода FragmentStateAdapter:
Теперь две функции, которые позволяют подменять фрагменты
Пример использования
Все готово — у каждого фрагмента есть ссылка на адаптер, значит есть возможность заменить фрагмент на любой странице, а самое главное (наиболее используемое на практике) — есть возмжность заменить самого себя.
Например, фрагмент, по умолчанию, отображаемый на первой странице:
Мысли в слух
Аккуратно, если фрагменты тяжелые, — надо задуматься об очищении mapOfFragment.
Возможно, стоит хранить Class вместо BaseFragment. Но тогда придется инициализировать их каждый раз в createFragment(). Меньше памяти, больше времени. Что думаете?
Источник
Русские Блоги
Использование ViewPager2
Справочник статей
Введение
ViewPager2 — это компонент, добавленный Google в пакет компонентов androidx, и он достиг стабильной версии 1.0.0.
Почему Google хочет этот компонент? Чиновник сказал это:
Простое понимание исходного кода
ViewPager2 наследует ViewGroup, поэтому он не совместим с ViewPager. Внутренним ядром является RecyclerView + LinearLayoutManager, который на самом деле является слоем RecyclerView. Все функции работают вокруг RecyclerView и LinearLayoutManager.
Мы знаем, что SnapHelper используется, чтобы помочь RecyclerView выровнять Item по определенной позиции в конце прокрутки.PagerSnapHelperЭффект заключается в том, чтобы текущий элемент отображался по центру в конце скольжения и ограничивался только одной страницей за раз, а не быстрым и непрерывным скольжением, чтобы он был очень похож на исходное взаимодействие с пейджером и достигал аналогичного интерактивного эффекта. Так что вам нужно настроить SnapHelper:
ViewPager2 требуется адаптер для отображения содержимого. Адаптер может быть RecyclerView.Adapter или FragmentStateAdapter, а ViewPager2 — это конечный класс, поэтому его нельзя расширять.
Изменить точку
новая функция
- Поддержка макета RTL
- Поддерживает вертикальную прокрутку
- Поддержка отключения предварительной загрузки offscreenPageLimit
- Полная поддержка notifyDataSetChanged (и частичное обновление)
- Легко включить и отключить пользовательский удар (setUserInputEnabled)
- Представлен MarginPageTransformer для увеличения промежутков между страницами.
- Введите CompositePageTransformer для объединения нескольких PageTransformer
- Поскольку ViewPager2 поддерживается Recyclerview, он также поддерживает ItemDecorator,DiffUtilПодождите
Изменения API
- FragmentStateAdapter заменяет оригинальный FragmentStatePagerAdapter
- RecyclerView.Adapter заменил оригинальный PagerAdapter
- registerOnPageChangeCallback заменяет оригинальный addPageChangeListener
Примечание. Не забудьте отменить регистрацию OnPageChangeCallback
Обычно используемые API
- void setOrientation (int direction) устанавливает ориентацию макета
- void setUserInputEnabled (логическое значение включено) Установите, разрешать ли пользовательский ввод / касание
- int getCurrentItem () Получить текущий индекс элемента
- void setCurrentItem (int item) Установить текущий индекс элемента
- setOffscreenPageLimit (int limit) Установите количество страниц загрузки вне экрана
- setPageTransformer (ViewPager2.PageTransformer преобразователь) Установите эффект преобразования, когда страница скользит
- registerOnPageChangeCallback (OnPageChangeCallback) обратный вызов изменения страницы регистрации
- unregisterOnPageChangeCallback (обратный вызов ViewPager2.OnPageChangeCallback) Отмена регистрации обратного вызова изменения страницы
Больше может пойти самостоятельноViewPager2Посмотреть.
Внедрить реализацию
Обратите внимание, что viewpager2 находится в androidx, и библиотеки поддержки androidx и android не могут сосуществовать, поэтому внимание библиотеки поддержки в проекте должно быть перенесено на androidx, что здесь не детализировано. Я сам Google.
Официальная демонстрация
ViewPager2 with Views
Этот пример используется, чтобы показать добавление просмотров
Код:
Макет XML
Определить RecyclerView.Adapter
Из приведенного выше кода видно, что адаптер такой же, как при использовании RecyclerView.
ViewPager2 with Fragments
Этот пример используется, чтобы показать добавление фрагментов
Код:
Макет XML
Используйте FragmentStateAdapter
Комбинация ViewPager2 и Fragment требует использования FragmentStateAdapter. FragmentStateAdapter фактически наследует RecyclerView.Adapter. Если вам интересно, вы можете взглянуть на исходный код.
ViewPager2 with TabLayout
Этот пример используется для демонстрации использования TabLayout
Код:
Макет XML
Примечание: TabLayout очень просто интегрировать со старой версией ViewPager, просто добавьте его как вложенный элемент ViewPager и установите свойство layout_gravity.
Однако ViewPager2 не принимает TabLayout в качестве дочерней привязки View.
Определить RecyclerView.Adapter
Связывание TabLayout и ViewPager2
Примечание. В Androidx TabLayout не имеет метода setupWithViewPager (ViewPager2 viewpager2), но использует TabLayoutMediator для объединения TabLayout и ViewPager2.
ViewPager2 with PageTransformer
Этот пример используется для демонстрации добавления пользовательской анимации на слайд
Код:
Если вам нужно увеличить разрыв непосредственно на странице, вы можете использовать MarginPageTransformer, который также является новой функцией в ViewPager2. (Примечание: не может быть отрицательным)
[Ошибка передачи изображения по внешней цепочке, на исходном сайте может быть механизм защиты от кражи, рекомендуется сохранить изображение и загрузить его напрямую (img-BlKSdCth-1576063656447) (index_files / MarginPageTransformer.gif)]
Если есть несколько преобразователей страниц, вы можете использовать CompositePageTransformer для их объединения.
ViewPager2 with MultiPages
Этот пример используется для отображения страницы с элементами с обеих сторон, и вы можете видеть предыдущий и следующий элементы с обеих сторон.
Для реализации этой функции необходимо обратить внимание на следующие моменты:
1.setOffscreenPageLimit(int limit)
установлен в 1, элемент до и после предварительной загрузки
2.android:clipToPadding
Этот атрибут указывает: Используется для определения, позволяет ли ViewGroup рисовать с отступами. По умолчанию это правда. Если это правда, часть отступа будет обрезана в нарисованной области. Если false, то область рисования элемента управления содержит часть заполнения. Так что здесь это должно быть установлено в false.
3. Установите левый и правый отступ для ViewPager2 и левый и правый поля для элемента
ViewPager2 with notifyDataSetChanged
Я использовал notifyDataSetChanged от ViewPager, чтобы знать, что при обновлении количества представлений в ViewPager будут возникать некоторые проблемы. Необходимо переписать метод getItemPosition, чтобы вернуть его в POSITION_NONE, прежде чем он действительно обновится.
А NotificationDataSetChanged из ViewPager2 фактически использует notifyDataSetChanged из RecyclerView, поэтому у него не будет этой проблемы, он также поддерживает частичное обновление и может использовать класс DiffUtil для обновления (примечание: если вы используете DiffUtil, вам нужно Переопределите методы getItemId () и containsItem ()).
Примеры:
Код:
ViewPager2 with fake drag
В этом примере показано моделирование действия перетаскивания, в основном с использованием методов beginFakeDrag (), fakeDragBy () и endFakeDrag ().
Пример:
Код:
Подробный код можно посмотретьViewPaer2 demo。
О offscreenPageLimit (предварительная загрузка)
ViewPager
Диаграмма загрузки ViewPager по умолчанию выглядит следующим образом:
При переключении на текущую страницу макет слева и справа будет предварительно загружен по умолчанию в ViewPager Хотя Вид с обеих сторон не виден. из-за ViewPager Верный offscreenPageLimit Ограничение установлено, в OffPagePageLimit, установленном в 0, в ViewPager эффект фактически не является значением по умолчанию 1 (см. Исходный код ниже), что приводит к неизбежной предварительной загрузке страницы, в Fragment сотрудничать ViewPager Эта проблема также существует во время использования.
ViewPager2
В предыдущей точке изменения упоминалось, что ViewPager2 поддерживает offscreenPageLimit, что означает, что только текущая страница будет загружена в ситуации по умолчанию или при установке значения по умолчанию. Давайте посмотрим на исходный код ViewPager2
Видно, что поддерживается только значение больше 0 или значение по умолчанию (-1). Затем проверьте исходный код и найдите метод getOffscreenPageLimit () в ViewPager2.LinearLayoutManagerImpl внутренний calculateExtraLayoutSpace Метод используется.
это calculateExtraLayoutSpace Понятно, что метод заключается в определении дополнительного пространства в макете. Пространство по умолчанию равно ширине и высоте RecyclerView. Чтобы определить это пространство, предназначенное для увеличения макета, необходимо указать параметры метода. extraLayoutSpace Это массив int длиной 2. Первый фрагмент данных принимает дополнительное пространство слева и сверху, а второй фрагмент данных принимает дополнительное пространство справа и снизу, поэтому приведенный выше код указывает, что он не обрабатывается, если он равен значению по умолчанию, в противном случае он слева и справа. Вверх и вниз offscreenSpace ;так что OffscreenPageLimit Это на самом деле увеличено LinearLayoutManager Макет пространства.
демоверсия
Чтобы проверить эффект загрузки, я использовал LinearLayout для отображения обоих ViewPager и ViewPager2, установил один и тот же элемент и данные, а затем применил Layout Inspector для получения структуры макета обоих. В результате получилось следующее:
1. offscreenPageLimit по умолчанию
2. Установите offscreenPageLimit в 1
Источник