🧛 Fragula is a swipe-to-dismiss extension for navigation component library for Android

Overview

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.

Android CI License Android Arsenal

Showcase


Table of Contents

  1. Gradle Dependency
  2. The Basics
  3. More Options
    1. Destination Arguments
    2. Multiple BackStacks
  4. Swipe Direction
  5. Swipe Transitions
  6. Theming

Gradle Dependency

MavenCentral

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:

">

<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 destinations in graph with as shown below:

... ">

<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.

... ">

<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.

">

<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:

... ... ... #000000 0.10 1.3 300 ">
<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
    <item name="colorPrimary">...item>
    <item name="colorPrimaryDark">...item>
    <item name="colorAccent">...item>

    
    <item name="fgl_dim_color">#000000item>

    
    <item name="fgl_dim_amount">0.10item>

    
    <item name="fgl_parallax_factor">1.3item>
   
    
    <item name="fgl_anim_duration">300item>
   
style>
Comments
  • how to stop one fragment in navHost not to implement swipe Please let me know is this possible? I have map fragment when change fragment to swipeable my map scrolling stops

    how to stop one fragment in navHost not to implement swipe Please let me know is this possible? I have map fragment when change fragment to swipeable my map scrolling stops

    Please consider making a Pull Request if you are capable of doing so.

    Is your feature request related to a problem? Please describe. A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

    Describe the solution you'd like A clear and concise description of what you want to happen.

    Describe alternatives you've considered A clear and concise description of any alternative solutions or features you've considered.

    Additional context Add any other context or screenshots about the feature request here.

    feature 
    opened by arsalanImtiaz455 4
  • Creating rememberSwipeBackNavigator

    Creating rememberSwipeBackNavigator

    Creating a SwipeBackNavigator remember to act more like the bottom sheet from accompanist. This means it won't be added to the provider repeatedly.

    I ran into an issue when changing the theme where my app crashed. I looked at logcat and saw:

    java.lang.IllegalStateException: Navigator com.fragula2.compose.SwipeBackNavigator@1665b1f is replacing an already attached com.fragula2.compose.SwipeBackNavigator@b83b225
    

    Realizing that it was because of:

    navController.apply {
                navigatorProvider.addNavigator(SwipeBackNavigator())
            }
    

    It was being added whenever it would be recomposed.

    This pr should fix that.

    I do love the library and it's really cool!

    opened by jakepurple13 2
  • Apply animation to `navigateUp()`

    Apply animation to `navigateUp()`

    Describe the solution you'd like I hope apply scroll animation when call navController().navigateUp()

    Describe alternatives you've considered I found accompanist-navigation-animation:0.16.1, which does not have gestures, but does this issue: https://medium.com/androiddevelopers/animations-in-navigation-compose-36d48870776b

    Is it possible to combine Fragula with it?

    feature 
    opened by neslxzhen 1
  • Jetpack Compose improvements

    Jetpack Compose improvements

    Missing features

    1. [ ] Slide transition using NavController.popBackStack() method
    2. [ ] Changing the swipe direction
    3. [ ] Swipe position listener

    Bugfixes

    1. [ ] Slide animation repeats on recomposition (when changing device orientation)
    2. [ ] All of the backstack entries (screens) are rendered at the same time
    bug feature 
    opened by massivemadness 0
  • BackStack issue with `<fragment>` destinations

    BackStack issue with `` destinations

    Describe the bug There's an issue when navigating from <swipeable> to <fragment> destination, the fragment will not be added to the backstack, which makes impossible to go back using popBackStack() or navigateUp() methods.

    To Reproduce Steps to reproduce the behavior:

    1. Make <swipeable> your start destination
    2. Navigate to a <fragment> destination
    3. Call popBackStack() to return to the previous fragment

    Any ideas of how to fix The issue is not exactly in SwipeBackNavigator, It's the default behavior of androidx.navigation.fragment.FragmentNavigator, which depends on the backstack size to decide whether it should add a transaction to the backstack or not.

    Снимок экрана 2022-03-19 в 13 39 43 Снимок экрана 2022-03-19 в 13 41 00 bug 
    opened by massivemadness 0
Releases(2.4.1)
  • 2.4.1(Dec 17, 2022)

    ChangeLog

    • Fixed: Crash on recomposition (thanks to @jakepurple13, 5d63bf864d01255d17bbd9a7a294fab0974d86f5)
    • Rewritten Jetpack Compose sample (2a9d333b3422ceaf7731fa59bd0e5ec30e9fd6f7)
    • Bump library versions (db3c74017c7ef6dba68ba7f25dec920c675dbafe)
      • AGP to 7.3.1
      • Target SDK to 33
      • androidx.navigation to 2.5.3
      • androidx.compose to 1.3.1
    • Minor improvements

    Full list of changes: https://github.com/massivemadness/Fragula/compare/2.4...2.4.1

    Source code(tar.gz)
    Source code(zip)
  • 2.4(Jun 19, 2022)

    ChangeLog

    • Added: Support for Jetpack Compose (5f808a4660eb44f649ad0ef68f29dced589db342)
    • Added: Attribute fgl_elevation (662fcd7b7c723756fcb836ce9ba364562d375145)
    • Downgrade kotlin to v1.6.10 to support compose (dad8cd6da09e54d332db063accc5b5d0042241c0)

    Full list of changes: https://github.com/massivemadness/Fragula/compare/2.3...2.4

    Source code(tar.gz)
    Source code(zip)
  • 2.3(Apr 29, 2022)

    ChangeLog

    • Added: Better swipe back animation (219626b231a7ccf0830f4a0cd503ef6d2b9bd718)
    • Fixed: Rare crash in sample app (9d5ba198f1d7eff1cdb0819c6f6a3a25b129fb60)
    • Updated kotlin library to v1.6.21 (36928aba3499ef9c70f78e768d3f9c13f7797047)
    • Minor improvements (ed3d5d0bf6db83148f1724ce37821dc7d226a6aa)

    Full list of changes: https://github.com/massivemadness/Fragula/compare/2.2...2.3

    Source code(tar.gz)
    Source code(zip)
  • 2.2(Apr 12, 2022)

    ChangeLog

    • Added: Attribute fgl_parallax_factor (bf718ba3df7458e0191dd1a256f0418ff13424f0)
    • Fixed: Android Studio auto-completion in NavGraph (67fc871568c85260f4a49f4b4bdc30caf255da30)
    • Updated fgl_dim_color and fgl_dim_amount default values (37ae6c58f50a6928f6a2f66b380a6582189f57bb)
    • Updated androidx.navigation library to v2.4.2 (fb59f3b059593f90e934b22fafc04668a7a5abb7)
    • Minor improvements (fe2f6c94aeb5a28e59f6b7085f56882a2e0be4a9)

    Full list of changes: https://github.com/massivemadness/Fragula/compare/2.1...2.2

    Source code(tar.gz)
    Source code(zip)
  • 2.1(Apr 4, 2022)

    ChangeLog

    • Added: Support for different swipe directions (9ecaf4f5b8adc575acf5b1c16b0d41d8a4192803)
    • Added: Allow to enable/disable user initiated scrolling (f544b4f1b4f8c1d82142347e6615662f26b9f714)
    • Fixed: Animation should feel much faster than before (26300297a093af154428c0d92079ecc5fe3fd7a4)
    • Light theme in sample app (f15012aa1f546f49db79893985c4f82b0ac4c8a4)
    • Internal improvements

    Full list of changes: https://github.com/massivemadness/Fragula/compare/2.0...2.1

    Source code(tar.gz)
    Source code(zip)
  • 2.0(Mar 27, 2022)

    ChangeLog

    Stable release of com.fragula2.fragula-core library.

    • Added: The id property to StackEntry object (c0399bf83947bdca26783432207f15e43b391eaf)
    • Improved sample application (25f02e60f9f09a540aa148a0c8c0c1b60021edc1)

    What's new since 1.0?

    • Support for NavComponent library
    • Migration to ViewPager2
    • Theme attributes support
    • Internal architecture improvements

    Full list of changes: https://github.com/massivemadness/Fragula/compare/2.0-rc02...2.0

    Source code(tar.gz)
    Source code(zip)
  • 2.0-rc02(Mar 23, 2022)

    ChangeLog

    This release candidate version is going to be the last before the final release

    • Internal improvements (ad74930f4dba4c0ea5131ae1eb775434434a64b5, c6d7699f708ae2f89e742db046acb7c74109df38, 9badd6ed016ae77490899fc2794e238f3f27657c)

    Full list of changes: https://github.com/massivemadness/Fragula/compare/2.0-rc01...2.0-rc02

    Source code(tar.gz)
    Source code(zip)
  • 2.0-rc01(Mar 19, 2022)

    ChangeLog

    • Added: Attribute fgl_anim_duration (3059146962eb5252cbb6fbc642760f93d4521fb0)
    • Fixed: Redundant swipe animation for underneath fragment (e4c233723cc956e70a981eee55d4a67d7925f632)
    • Internal improvements (9fe040be773e63e4c4627b2821177cee62639ab2)

    Full list of changes: https://github.com/massivemadness/Fragula/compare/2.0-beta02...2.0-rc01

    Source code(tar.gz)
    Source code(zip)
  • 2.0-beta02(Mar 14, 2022)

    ChangeLog

    • Fixed: Click events during swipe animation (7d5dfba52f59ab70476f44843de078886d61be7b)
    • Fixed: Missing navigation events (navigate, popBackStack) during swipe animation (ee3aef25d7c5f8e60d00af6e3304dbdb7dad2fc1)
    • Fixed: Empty view when calling 'popBackStack' multiple times (36e0a94b4bf7532dd44724ccb1091a83de463ecf)
    • Completely redesigned sample app (40a80a2df67996a2de2aa826e0fa1f1eb75ef753)
    • Internal improvements

    Full list of changes: https://github.com/massivemadness/Fragula/compare/2.0-beta01...2.0-beta02

    Source code(tar.gz)
    Source code(zip)
  • 2.0-beta01(Mar 12, 2022)

    ChangeLog

    • Added: SwipeController for animations (834896b527f9992fcbfe196a2399b90f514e8cb6)
    • Added: Navigation Drawer Sample (190dc4fdc0c1aab960832424e617d36a8572fed7)
    • Slightly redesigned sample app (9dd479053f71f4a1c64a26a6ac396aea7b8826c4)
    • Internal improvements

    Full list of changes: https://github.com/massivemadness/Fragula/compare/2.0-alpha03...2.0-beta01

    Source code(tar.gz)
    Source code(zip)
  • 2.0-alpha03(Mar 11, 2022)

    ChangeLog

    • Added: Elevation effect (17948a0d4b8ed0501850a25ae3c86fd4bd591eae)
    • Added: Attribute fgl_dim_amount (bcd70eb4bd7373373340e1c8601f0bc16a419e6e)
    • Fixed: Click events during swipe animation (08e087f91021561f983a09b8c82d5334fcd45b48)
    • Internal improvements

    Full list of changes: https://github.com/massivemadness/Fragula/compare/2.0-alpha02...2.0-alpha03

    Source code(tar.gz)
    Source code(zip)
  • 2.0-alpha02(Mar 10, 2022)

    ChangeLog

    • Added: Global Theming support (616542cd4bbb33f9676b8847502712ee19003fe7)
    • Fixed: popBackStack animation issue (ddf376bb42b67505641f1f49144b244aac63fb09)
    • Internal improvements

    Full list of changes: https://github.com/massivemadness/Fragula/compare/2.0-alpha01...2.0-alpha02

    Source code(tar.gz)
    Source code(zip)
  • 2.0-alpha01(Mar 9, 2022)

Owner
Dmitry Rubtsov
20 y.o. Middle Android Engineer @ozontech
Dmitry Rubtsov
Navigation Component: THE BEST WAY to create navigation flows for your app

LIVE #017 - Navigation Component: A MELHOR FORMA de criar fluxos de navegação para o seu app! Código fonte do projeto criado na live #017, ensinando c

Kaique Ocanha 4 Jun 15, 2022
Dismiss your keyboard by tapping anywhere outside it.

Keyboard Dismisser What is this? Keyboard Dismisser is a simple library that allows you to dismiss keyboard by tapping anywhere outside it. Currently

Gabriel Samojło 49 Nov 28, 2021
NavigationComponent-SendingData - Android Navigation Component : Pass value (arguments) in Fragments

NavigationComponent-SendingData Android Navigation Component : Pass value (argum

Reyhaneh Ezatpanah 1 Dec 28, 2021
NavigationSafeArgs - Passing data with Navigation Component in Android

Navigation SafeArgs Sample Passing data with Navigation Component in Android. Pr

Emine İNAN 0 Feb 13, 2022
A simple, highly customizable compose navigation component for Android & Desktop platform.

介绍 一个简单并提供高度扩展功能的 Compose 导航组件,同时支持 Android 和 Desktop 平台。 常用功能 使用 下载 // Android implementation("io.github.succlz123:compose-screen-android:0.0.1") //

Ning 15 Nov 24, 2022
A Simple App to implement Navigation Architecture Component.

Android Navigation codelab Content: https://codelabs.developers.google.com/codelabs/android-navigation/ License Copyright 2018 The Android Open Source

Gilbert Ngeno 0 Nov 5, 2021
Alligator is a modern Android navigation library that will help to organize your navigation code in clean and testable way.

Alligator Alligator is a modern Android navigation library that will help to organize your navigation code in clean and testable way. Features Any app

Artur Artikov 290 Dec 9, 2022
[ACTIVE] Simple Stack, a backstack library / navigation framework for simpler navigation and state management (for fragments, views, or whatevers).

Simple Stack Why do I want this? To make navigation to another screen as simple as backstack.goTo(SomeScreen()), and going back as simple as backstack

Gabor Varadi 1.3k Jan 2, 2023
A sleek, out of the box, easy to understand and use, swipe gesture based Navigational Library for android.

Facilis Swipe gesture based navigational library for Android. Watch Demo Video: Getting Started To get this project into your build: Gradle Add it in

Prem Suman 35 Feb 15, 2022
Android multi-module navigation built on top of Jetpack Navigation Compose

MultiNavCompose Android library for multi-module navigation built on top of Jetpack Navigation Compose. The goal of this library is to simplify the se

Jeziel Lago 21 Dec 10, 2022
DSC Moi University session on using Navigation components to simplify creating navigation flow in our apps to use best practices recommended by the Google Android Team

Navigation Components Navigate between destination using safe args How to use the navigation graph and editor How send data between destinations Demo

Breens Mbaka 6 Feb 3, 2022
Bottom-App-Bar-with-Bottom-Navigation-in-Jetpack-compose-Android - Bottom App Bar with Bottom Navigation in Jetpack compose

Bottom-App-Bar-with-Bottom-Navigation-in-Jetpack-compose-Android This is simple

Shruti Patel 1 Jul 11, 2022
New style for app design simple bottom navigation with side navigation drawer UI made in Jetpack Compose.😉😎

BottomNavWithSideDrawer New style for app design simple bottom navigtaion with side navigation drawer UI made in Jetpack Compose. ?? ?? (Navigation Co

Arvind Meshram 5 Nov 24, 2022
Navigation Drawer Bottom Navigation View

LIVE #019 - Toolbar, Navigation Drawer e BottomNavigationView com Navigation Com

Kaique Ocanha 6 Jun 15, 2022
🎉 [Android Library] A light-weight library to easily make beautiful Navigation Bar with ton of 🎨 customization option.

Bubble Navigation ?? A light-weight library to easily make beautiful Navigation Bars with a ton of ?? customization options. Demos FloatingTopBarActiv

Gaurav Kumar 1.7k Dec 31, 2022
A small navigation library for Android to ease the use of fragment transactions & handling backstack (also available for Jetpack Compose).

A small navigation library for Android to ease the use of fragment transactions & handling backstack (also available for Jetpack Compose).

Kaustubh Patange 88 Dec 11, 2022
A simple navigation library for Android 🗺️

Enro ??️ A simple navigation library for Android "The novices’ eyes followed the wriggling path up from the well as it swept a great meandering arc ar

Isaac Udy 216 Dec 16, 2022
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.

implementation "com.vladmarkovic.briefactions:briefactions:$briefActionsVersion" Benefits Why use brief-actions library pattern: Prevent short-term ac

null 2 Dec 22, 2022
🛸Voyager is a pragmatic navigation library built for, and seamlessly integrated with, Jetpack Compose.

Voyager is a pragmatic navigation library built for, and seamlessly integrated with, Jetpack Compose.

Adriel Café 831 Dec 26, 2022