Description
Fragula is a swipe-to-dismiss extension for navigation component library for Android. It is an adaptation of an earlier version created by @shikleev and now maintained in this repository.
Fragula 2 alternatives and similar packages
Based on the "Navigation" category.
Alternatively, view Fragula alternatives based on common mentions on social networks and blogs.
-
SlidingTutorial
Android Library for making animated tutorials inside your app -
Compose Destinations
Annotation processing library for type-safe Jetpack Compose navigation with no boilerplate. -
Bubble Navigation
🎉 [Android Library] A light-weight library to easily make beautiful Navigation Bar with ton of 🎨 customization option. -
FragNav
An Android library for managing multiple stacks of fragments -
RecyclerTabLayout
An efficient TabLayout library implemented with RecyclerView. -
Duo Navigation Drawer
A flexible, easy to use, unique drawer library for your Android project. -
AnimatedBottomBar
A customizable and easy to use BottomBar navigation view with sleek animations, with support for ViewPager, ViewPager2, NavController, and badges. -
BubbleTabBar
BubbleTabBar is a bottom navigation bar with customizable bubble-like tabs -
Compose Navigation Reimagined
🌈 Type-safe navigation library for Jetpack Compose -
Alligator
Alligator is a modern Android navigation library that will help to organize your navigation code in clean and testable way. -
PagerSlidingTabStrip
An interactive indicator to navigate between the different pages of a ViewPager -
Okuki
Okuki is a simple, hierarchical navigation bus and back stack for Android, with optional Rx bindings, and Toothpick DI integration. -
Dual-color-Polyline-Animation
This library will help to show the polyline in dual color similar as Uber. -
Keyboard Dismisser
Dismiss your keyboard by tapping anywhere outside it. -
TypedNavigation
A lightweight library to help you navigate in compose with well typed functions. -
Facilis
A sleek, out of the box, easy to understand and use, swipe gesture based Navigational Library for android. -
fragstack
Memory efficient android library for managing individual fragment backstack. -
what3words Autosuggest EditText
An Android library to use what3words autosuggest -
AndroidBriefActions
Android library for sending and observing non persistent actions such as showing a message; nice readable way to call navigation actions from ViewModel or Activity/Fragment.
Appwrite - The open-source backend cloud platform
* Code Quality Rankings and insights are calculated and provided by Lumnify.
They vary from L1 to L5 with "L5" being the highest.
Do you think we are missing an alternative of Fragula 2 or a related project?
README
Fragula 2
Fragula is a swipe-to-dismiss extension for navigation component library for Android.
It is an adaptation of an earlier version created by @shikleev and now maintained in this repository.
[Showcase](.github/images/showcase.gif)
Table of Contents
Gradle Dependency
Add this to your module’s build.gradle
file:
dependencies {
...
implementation 'com.fragula2:fragula-core:2.2'
}
The fragula-core
module contains everything you need to get started with the library. It contains all core and normal-use functionality.
The Basics
First, you need to replace NavHostFragment
with FragulaNavHostFragment
in your layout:
<!-- 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:name="com.fragula2.FragulaNavHostFragment"
android:id="@+id/nav_host"
app:navGraph="@navigation/nav_graph"
app:defaultNavHost="true" />
Second, you need to replace your <fragment>
destinations in graph with <swipeable>
as shown below:
<!-- nav_graph.xml -->
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_graph"
app:startDestination="@id/detailFragment">
<swipeable
android:id="@+id/detailFragment"
android:name="com.example.fragula.DetailFragment"
android:label="DetailFragment"
tools:layout="@layout/fragment_detail" />
...
</navigation>
Finally, you need to set opaque background and layout direction flag to your fragment’s root layout to avoid any issues 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="local">
...
</androidx.constraintlayout.widget.ConstraintLayout>
Now if you open the app you'll see that you can swipe fragments like in Telegram, Slack and many other messaging apps.
More Options
Destination Arguments
In general, you should work with Fragula as if you would work with normal fragments. You should strongly prefer passing only the minimal amount of data between destinations, as the total space for all saved states is limited on Android.
First, add an argument to the destination:
<swipeable
android:id="@+id/detailFragment"
android:name="com.example.fragula.DetailFragment">
<argument
android:name="itemId"
app:argType="string" />
</swipeable>
Second, create a Bundle object and pass it to the destination using navigate()
as shown below:
val bundle = bundleOf("itemId" to "123")
findNavController().navigate(R.id.detailFragment, bundle)
Finally, in your receiving destination’s code, use the getArguments()
method to retrieve the
Bundle and use its contents:
val textView = view.findViewById<TextView>(R.id.textViewItemId)
textView.text = arguments?.getString("itemId")
It's strongly recommended to use Safe Args plugin for navigating and passing data, because it ensures type-safety.
Multiple BackStacks
Currently multiple backstacks is not supported, which means you can’t safely use extensions such
as setupWithNavController(...)
without losing your current backstack.
This issue affects both BottomNavigationView
and NavigationView
widgets.
Swipe Direction
If you want to change the direction of swipe gesture, you can do that by setting
app:swipeDirection="..."
manually in your navigation container. This example below sets up
vertical swipe direction.
<!-- 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:name="com.fragula2.FragulaNavHostFragment"
android:id="@+id/nav_host"
app:swipeDirection="top_to_bottom"
app:navGraph="@navigation/nav_graph"
app:defaultNavHost="true" />
You can use either left_to_right
(default) or right_to_left
for horizontal direction.
For vertical direction you can use only top_to_bottom
, the bottom_to_top
is not supported due
to internal ViewPager2 restrictions.
Note: If you having an issues with nested scrollable views, this appears to be a scroll issue in ViewPager2. Please follow Google’s example to solve this.
Swipe Transitions
You may want to know when the scrolling offset changes to make smooth transitions inside your
fragment view. To start listening scroll events you need to retrieve SwipeController
and set
OnSwipeListener
as shown below:
Note: Currently shared element transitions between destinations are not supported in any form.
class DetailFragment : Fragment(R.layout.fragment_detail) {
private lateinit var swipeController: SwipeController
private lateinit var swipeListener: OnSwipeListener
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
...
swipeController = findSwipeController()
swipeListener = OnSwipeListener { position, positionOffset, positionOffsetPixels ->
// TODO animate views using `positionOffset` or `positionOffsetPixels`.
// the `position` points to the position of the fragment in backstack
}
swipeController.addOnSwipeListener(swipeListener)
}
override fun onDestroyView() {
super.onDestroyView()
swipeController.removeOnSwipeListener(swipeListener)
}
}
Remember: you must remove the listener when the fragment view is destroyed.
Theming
In most of the cases there is no need to change any values, but if you wish to override these, there are attributes provided:
<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
<item name="colorPrimary">...</item>
<item name="colorPrimaryDark">...</item>
<item name="colorAccent">...</item>
<!--
This overrides the color used for the dimming when fragment is being dragged.
The default value is #000000 for both light and dark themes.
-->
<item name="fgl_dim_color">#000000</item>
<!--
This overrides the amount of dimming when fragment is being dragged.
Think of it as a `fgl_dim_color` alpha multiplier.
-->
<item name="fgl_dim_amount">0.10</item>
<!--
This overrides the parallax multiplier when fragment is being dragged.
It determines how much the underneath fragment will be shifted
relative to the visible fragment (that is being dragged).
-->
<item name="fgl_parallax_factor">1.3</item>
<!--
This overrides the duration of swipe animation using `navController.navigate(...)`
and `navController.popBackStack()` methods.
-->
<item name="fgl_anim_duration">300</item>
</style>
*Note that all licence references and agreements mentioned in the Fragula 2 README section above
are relevant to that project's source code only.