- umarhussain15 / SwipeDisabledViewPager.java
- ViewPager2 | Android Developers : Disable swiping in a specific direction using “fakeDrag”.
- FakeDrag
- ViewPager2 | Android Developers : Disable swiping in a specific direction using “fakeDrag”.
- FakeDrag
- Как работать с ViewPager2
- Новые фичи
- Что изменилось?
- Добавление зависимости
- Настройка
- Вертикальная прокрутка
- Использование FragmentStateAdapter
- Улучшенный OnPageChangeCallback
- Внимание!
- Android — ViewPager2 — заменяем фрагменты на лету (программно)
- Задача
- Результат
- Дисклеймер (не читать, вода)
- Решение
- Верстка
- Интерфейсы
- Связь активити и ViewPager2
- Адаптер для ViewPager2 — всё здесь
- Пример использования
- Мысли в слух
umarhussain15 / SwipeDisabledViewPager.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
SwipeDisabledViewPager |
android : id = » @+id/container « |
android : layout_width = » match_parent « |
android : layout_height = » wrap_content »/> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
import android.content.Context ; |
import android.support.v4.view.ViewPager ; |
import android.util.AttributeSet ; |
import android.view.MotionEvent ; |
public class SwipeDisabledViewPager extends ViewPager < |
public SwipeDisabledViewPager ( Context context ) < |
super (context); |
> |
public SwipeDisabledViewPager ( Context context , AttributeSet attrs ) < |
super (context, attrs); |
> |
@Override |
public boolean onTouchEvent ( MotionEvent ev ) < |
// returning false will not propagate the swipe event |
return false ; |
> |
@Override |
public boolean onInterceptTouchEvent ( MotionEvent ev ) < |
return false ; |
> |
> |
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Источник
ViewPager2 | Android Developers : Disable swiping in a specific direction using “fakeDrag”.
Aug 20 · 3 min read
So you want to disable the swiping, but only in the specific direction let’s just say to the right.
You can easily do that by creating a custom class inherits from viewPager and override two methods: “ onTouchEvent()” and “ onInterceptTouchEvent()” and return true or false to disable and enable the swiping on certain touch events i.e say swiping.
But if you want to upgrade to ViewPager 2 in your project, unfortunately, you can’t do that because ViewPager2 is the final class.
So now, how do we do that in ViewPager2? well, we can do it by using fakeDrag introduced in Viewpager2. Let’s first see what the fakeDrag Is.
FakeDrag
Yeah, so It’s a feature that lets you control the swiping from another place like a slider, and allows you to make something like a touchpad to control your ViewPager 2.
So what I’m going to do is to use the same code above but instead of inheriting from ViewPager, we can do this with any views or view-group and then listen to its touch event, and then we can use this as a touchpad that overlays on top of Our ViewPager2.
Let’s understand this with code.
The first thing to do is to disable the swipe in ViewPager 2 by simply calling :
Then in the XML layout file, we can parent the ViewPager 2 with GestureOverlayView
note that we are using GuestureOverlayView. If this is any other view, let’s say FrameLayout then what happens is that we can’t use ViewPager2 touch events.
also, we are making “gestureColor” transparent so the user can’t see any gesture marker.
The next step is to add the guestureListner to the @+id/touchOverlay.
and then handleOnTouchEvent(event) which has the same code we saw earlier that we use when making a custom viewPage :
where the direction is defined as
here we have to call the viewPager2.beginFakeDrag() before doing the actual page dragging.
Then we calculate the delta value and pass it to viewPager2.fakeDragBy(delta) as to how much we wanna drag the page with our GuestureViewOverlay.
and finally, on MotionEvent cancel or action up we need to call the viewPager2.endFakeDrag().
There is another way to do this which you can check out here.
Источник
ViewPager2 | Android Developers : Disable swiping in a specific direction using “fakeDrag”.
Aug 20 · 3 min read
So you want to disable the swiping, but only in the specific direction let’s just say to the right.
You can easily do that by creating a custom class inherits from viewPager and override two methods: “ onTouchEvent()” and “ onInterceptTouchEvent()” and return true or false to disable and enable the swiping on certain touch events i.e say swiping.
But if you want to upgrade to ViewPager 2 in your project, unfortunately, you can’t do that because ViewPager2 is the final class.
So now, how do we do that in ViewPager2? well, we can do it by using fakeDrag introduced in Viewpager2. Let’s first see what the fakeDrag Is.
FakeDrag
Yeah, so It’s a feature that lets you control the swiping from another place like a slider, and allows you to make something like a touchpad to control your ViewPager 2.
So what I’m going to do is to use the same code above but instead of inheriting from ViewPager, we can do this with any views or view-group and then listen to its touch event, and then we can use this as a touchpad that overlays on top of Our ViewPager2.
Let’s understand this with code.
The first thing to do is to disable the swipe in ViewPager 2 by simply calling :
Then in the XML layout file, we can parent the ViewPager 2 with GestureOverlayView
note that we are using GuestureOverlayView. If this is any other view, let’s say FrameLayout then what happens is that we can’t use ViewPager2 touch events.
also, we are making “gestureColor” transparent so the user can’t see any gesture marker.
The next step is to add the guestureListner to the @+id/touchOverlay.
and then handleOnTouchEvent(event) which has the same code we saw earlier that we use when making a custom viewPage :
where the direction is defined as
here we have to call the viewPager2.beginFakeDrag() before doing the actual page dragging.
Then we calculate the delta value and pass it to viewPager2.fakeDragBy(delta) as to how much we wanna drag the page with our GuestureViewOverlay.
and finally, on MotionEvent cancel or action up we need to call the viewPager2.endFakeDrag().
There is another way to do this which you can check out here.
Источник
Как работать с ViewPager2
Прошло не так много времени с тех пор, как 7 февраля 2019 года Google выпустила альфа-версию Android ViewPager2. Более подробную информацию об этом релизе можно найти здесь. А сейчас давайте посмотрим, что из себя представляет ViewPager2.
Новые фичи
Что изменилось?
ViewPager2 выпущен для Android X, поэтому, если вы хотите его использовать, ваш проект должен использовать Android X. Давайте посмотрим, как мы можем использовать этот новый ViewPager2.
Добавление зависимости
Добавьте следующую зависимость в файл build.gradle на уровне приложения:
После этого синхронизируйте свой проект.
Настройка
Добавьте виджет 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 — 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(). Меньше памяти, больше времени. Что думаете?
Источник