diff --git a/enro-core/build.gradle b/enro-core/build.gradle index 43d51aa9..fbe59460 100644 --- a/enro-core/build.gradle +++ b/enro-core/build.gradle @@ -12,6 +12,7 @@ dependencies { implementation deps.androidx.activity implementation deps.androidx.recyclerview + compileOnly deps.androidx.navigation.fragment compileOnly deps.hilt.android kapt deps.hilt.compiler kapt deps.hilt.androidCompiler diff --git a/enro-core/src/main/java/dev/enro/core/fragment/AndroidxNavigationInterop.kt b/enro-core/src/main/java/dev/enro/core/fragment/AndroidxNavigationInterop.kt new file mode 100644 index 00000000..f346bb7e --- /dev/null +++ b/enro-core/src/main/java/dev/enro/core/fragment/AndroidxNavigationInterop.kt @@ -0,0 +1,36 @@ +package dev.enro.core.fragment + +import androidx.fragment.app.Fragment +import androidx.navigation.fragment.NavHostFragment +import dev.enro.core.NavigationContext +import dev.enro.core.fragment + +/** + * In applications that contain both AndroidX Navigation and Enro, the back pressed behaviour + * that is set by the NavigationHandleViewModel takes precedence over the back pressed behaviours that + * are set by AndroidX Navigation. + * + * This method checks whether or not a given NavigationContext is a part of the AndroidX Navigation, + * by checking whether or not the parent fragment is a NavHostFragment. If we see that it is a NavHostFragment, + * we'll execute popBackStack (which is the same behaviour the back pressed behaviour set by AndroidX Navigation), + * and then return true. + * + * If we decide that the NavigationContext does **not** belong to AndroidX Navigation, and + * is either part of Enro, or not part of any navigation framework, then we return false, to indicate that no + * action was performed. + */ +internal fun interceptCloseInstructionForAndroidxNavigation(context: NavigationContext): Boolean { + if (!isAndroidxNavigationOnTheClasspath) return false + val parent = context.fragment.parentFragment + if (parent is NavHostFragment) { + parent.navController.popBackStack() + return true + } + return false +} + +private val isAndroidxNavigationOnTheClasspath by lazy { + runCatching { NavHostFragment::class.java } + .map { true } + .getOrDefault(false) +} diff --git a/enro-core/src/main/java/dev/enro/core/fragment/DefaultFragmentExecutor.kt b/enro-core/src/main/java/dev/enro/core/fragment/DefaultFragmentExecutor.kt index 880b27c0..a45b3178 100644 --- a/enro-core/src/main/java/dev/enro/core/fragment/DefaultFragmentExecutor.kt +++ b/enro-core/src/main/java/dev/enro/core/fragment/DefaultFragmentExecutor.kt @@ -104,6 +104,8 @@ object DefaultFragmentExecutor : NavigationExecutor) { + if (interceptCloseInstructionForAndroidxNavigation(context)) return + if(!tryExecutePendingTransitions(context.fragment.parentFragmentManager)) { mainThreadHandler.post { /* diff --git a/enro/src/androidTest/java/dev/enro/core/JetpackNavigationInteropTest.kt b/enro/src/androidTest/java/dev/enro/core/AndroidxNavigationInteropTest.kt similarity index 74% rename from enro/src/androidTest/java/dev/enro/core/JetpackNavigationInteropTest.kt rename to enro/src/androidTest/java/dev/enro/core/AndroidxNavigationInteropTest.kt index b81181fd..2416eabe 100644 --- a/enro/src/androidTest/java/dev/enro/core/JetpackNavigationInteropTest.kt +++ b/enro/src/androidTest/java/dev/enro/core/AndroidxNavigationInteropTest.kt @@ -7,39 +7,14 @@ import android.widget.TextView import androidx.appcompat.app.AppCompatActivity import androidx.core.os.bundleOf import androidx.core.view.children -import androidx.fragment.app.Fragment -import androidx.navigation.fragment.NavHostFragment import androidx.navigation.fragment.findNavController import androidx.test.core.app.ActivityScenario import androidx.test.espresso.Espresso import dev.enro.TestFragment -import dev.enro.application -import dev.enro.core.controller.navigationController import dev.enro.expectFragment -import org.junit.After -import org.junit.Before import org.junit.Test -class JetpackNavigationInteropTest { - - val override = createOverride { - closed { - when (val parent = it.contextReference.parentFragment) { - is NavHostFragment -> parent.navController.popBackStack() - else -> defaultClosed(it) - } - } - } - - @Before - fun before() { - application.navigationController.addOverride(override) - } - - @After - fun after() { - application.navigationController.removeOverride(override) - } +class AndroidxNavigationInteropTest { @Test fun whenBackButtonIsPressed_thenJetpackNavigationReceivesBackButtonPress() {