Fragula is a swipe-to-dismiss extension for navigation element library for Android.
It’s an adaptation of an previous model created via @shikleev and now maintained on this repository.
Gradle Dependency
Upload this on your module’s construct.gradle
report:
dependencies {
...
implementation 'com.fragula2:fragula-core:2.1'
}
The fragula-core
module incorporates the entirety you want to get began with the library. It incorporates all core and normal-use capability.
The Fundamentals
First, you want to exchange NavHostFragment
with FragulaNavHostFragment
to your format:
<!-- activity_main.xml -->
<androidx.fragment.app.FragmentContainerView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:identify="com.fragula2.FragulaNavHostFragment"
android:identity="@+identity/nav_host"
app:navGraph="@navigation/nav_graph"
app:defaultNavHost="true" />
2nd, you want to exchange your <fragment>
locations in graph with <swipeable>
as proven underneath:
<!-- nav_graph.xml -->
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:equipment="http://schemas.android.com/equipment"
android:identity="@+identity/nav_graph"
app:startDestination="@identity/detailFragment">
<swipeable
android:identity="@+identity/detailFragment"
android:identify="com.instance.fragula.DetailFragment"
android:label="DetailFragment"
equipment:format="@format/fragment_detail" />
...
</navigation>
After all, you want to set opaque background and format route flag on your fragment’s root format to steer clear of any problems with swipe animation.
<!-- fragment_detail.xml -->
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:colorBackground"
android:layoutDirection="native">
...
</androidx.constraintlayout.widget.ConstraintLayout>
Now should you open the app you’ll be able to see that you’ll be able to swipe fragments like in Telegram, Slack and lots of different messaging apps.
Extra Choices
Vacation spot Arguments
Normally, you will have to paintings with Fragula as should you would paintings with usual fragments. You will have to strongly want passing best the minimum quantity of information between locations, as the full area for all stored states is proscribed on Android.
First, upload an issue to the vacation spot:
<swipeable
android:identity="@+identity/detailFragment"
android:identify="com.instance.fragula.DetailFragment">
<argument
android:identify="itemId"
app:argType="string" />
</swipeable>
2nd, create a Package object and go it to the vacation spot the use of navigate()
as proven underneath:
val package deal = bundleOf("itemId" to "123")
findNavController().navigate(R.identity.detailFragment, package deal)
After all, to your receiving vacation spot’s code, use the getArguments()
solution to retrieve the Package and use its contents:
val textView = view.findViewById<TextView>(R.identity.textViewItemId)
textView.textual content = arguments?.getString("itemId")
It is strongly really helpful to make use of Secure Args plugin for navigating and passing information, as it guarantees type-safety.
A couple of BackStacks
Lately more than one backstacks isn’t supported, this means that you’ll be able to’t safely use extensions reminiscent of BottomNavigationView.setupWithNavController(...)
with out dropping your present backstack.
Swipe Course
If you wish to trade the route of swipe gesture, you’ll be able to do this via surroundings app:swipeDirection="..."
manually to your navigation container. This situation underneath units up vertical swipe route.
<!-- activity_main.xml -->
<androidx.fragment.app.FragmentContainerView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:identify="com.fragula2.FragulaNavHostFragment"
android:identity="@+identity/nav_host"
app:swipeDirection="top_to_bottom"
app:navGraph="@navigation/nav_graph"
app:defaultNavHost="true" />
You’ll be able to use both left_to_right
(default) or right_to_left
for horizontal route. For vertical route you’ll be able to use best top_to_bottom
, you can’t use bottom_to_top
as a result of it is not supported because of inside ViewPager2 restrictions.
Web page Transitions
Chances are you’ll wish to know when the scrolling offset adjustments to make easy transitions inside of your fragment view. To begin listening scroll occasions you want to retrieve SwipeController
and set OnSwipeListener
as proven underneath:
Word: Lately shared part transitions between locations isn’t supported in any shape.
magnificence DetailFragment : Fragment(R.format.fragment_detail) {
non-public lateinit var swipeController: SwipeController
non-public lateinit var listener: OnSwipeListener
override a laugh onViewCreated(view: View, savedInstanceState: Package?) {
tremendous.onViewCreated(view, savedInstanceState)
...
swipeController = findSwipeController()
listener = OnSwipeListener { place, positionOffset, positionOffsetPixels ->
// TODO animate perspectives the use of `positionOffset` or `positionOffsetPixels`.
// the `place` issues to the placement of the fragment in backstack
}
swipeController.addOnSwipeListener(listener)
}
override a laugh onDestroyView() {
tremendous.onDestroyView()
swipeController.removeOnSwipeListener(listener)
}
}
Bear in mind: you should take away the listener when the fragment view is destroyed.
Theming
In many of the circumstances there’s no want to trade any values, however if you want to override those, there are attributes supplied:
<taste identify="AppTheme" mother or father="Theme.MaterialComponents.Gentle.NoActionBar">
<merchandise identify="colorPrimary">...</merchandise>
<merchandise identify="colorPrimaryDark">...</merchandise>
<merchandise identify="colorAccent">...</merchandise>
<!--
This overrides the colour used for the dimming when fragment is being dragged.
The default price is #121212 for each mild and darkish topics.
-->
<merchandise identify="fgl_dim_color">#121212</merchandise>
<!--
This overrides the quantity of dimming when fragment is being dragged.
Recall to mind it as a `fgl_dim_color` alpha multiplier.
-->
<merchandise identify="fgl_dim_amount">0.15</merchandise>
<!--
This overrides the period of swipe animation the use of `navController.navigate(...)`
and `navController.popBackStack()` strategies.
-->
<merchandise identify="fgl_anim_duration">300</merchandise>
</taste>