Skip to content

Commit

Permalink
Merge pull request #17 from riazati75/develop
Browse files Browse the repository at this point in the history
new: NavigationFragmentUtils
  • Loading branch information
riazati75 authored Oct 24, 2023
2 parents 246dec4 + ab7855c commit 32fe714
Show file tree
Hide file tree
Showing 7 changed files with 359 additions and 29 deletions.
13 changes: 12 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
buildscript {

repositories {
google()
}

dependencies {
classpath("androidx.navigation:navigation-safe-args-gradle-plugin:2.7.1")
}
}

plugins {
// android
id("com.android.application") version "8.3.0-alpha01" apply false
Expand All @@ -7,4 +18,4 @@ plugins {
}

group = "ir.farsroidx"
version = "1.3.14"
version = "1.3.15"
13 changes: 7 additions & 6 deletions core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ plugins {
id("org.jetbrains.kotlin.kapt")
// maven
id("maven-publish")
// androidx
id("androidx.navigation.safeargs")
}

android {
Expand Down Expand Up @@ -63,13 +65,12 @@ dependencies {
implementation("com.google.android.material:material:1.9.0")

// Lifecycle
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.1")
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2")
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2")

// Navigation
// implementation("androidx.navigation:navigation-ui-ktx:2.6.0")
// implementation("androidx.navigation:navigation-common-ktx:2.6.0")
// implementation("androidx.navigation:navigation-fragment-ktx:2.6.0")
implementation("androidx.navigation:navigation-ui-ktx:2.7.2")
implementation("androidx.navigation:navigation-fragment-ktx:2.7.2")

// Other
api("com.airbnb.android:lottie:6.1.0")
Expand Down Expand Up @@ -102,7 +103,7 @@ publishing {

groupId = "ir.farsroidx"
artifactId = "android-core"
version = "1.3.14"
version = "1.3.15"

afterEvaluate {
from(
Expand Down
1 change: 1 addition & 0 deletions core/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
xmlns:tools="http://schemas.android.com/tools">

<uses-permission android:name="android.permission.VIBRATE" />

<application>

<activity
Expand Down
219 changes: 216 additions & 3 deletions core/src/main/kotlin/ir/farsroidx/core/CoreActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,20 @@ import android.view.View
import androidx.annotation.CallSuper
import androidx.annotation.ColorRes
import androidx.annotation.DrawableRes
import androidx.annotation.IdRes
import androidx.annotation.StringRes
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.FragmentManager
import androidx.navigation.NavController
import androidx.navigation.NavDirections
import androidx.navigation.NavOptions
import androidx.navigation.Navigator
import androidx.navigation.findNavController
import ir.farsroidx.core.additives.autoViewDataBinding
import ir.farsroidx.core.model.SerializedData
import kotlinx.coroutines.Job
import java.io.Serializable

abstract class CoreActivity <VDB: ViewDataBinding> : AppCompatActivity() {
Expand All @@ -30,6 +39,18 @@ abstract class CoreActivity <VDB: ViewDataBinding> : AppCompatActivity() {

protected var useTransitionAnimation = true

protected var activeJob: Job? = null

private var pendingRequests = HashMap<Int, Bundle?>()

private var navHostFragmentIdCache: Int = -1

private var backStackChangeListener: FragmentManager.OnBackStackChangedListener? = null

private var destinationChangeListener: NavController.OnDestinationChangedListener? = null

private var wasPreviouslyShowingDialog = false

override fun onCreate(savedInstanceState: Bundle?) {

onBeforeInitializing(savedInstanceState)
Expand All @@ -39,6 +60,13 @@ abstract class CoreActivity <VDB: ViewDataBinding> : AppCompatActivity() {

super.onCreate(savedInstanceState)

@Suppress("UNCHECKED_CAST")
savedInstanceState?.let {
pendingRequests = (
it.getSerializable(PENDING_REQUESTS) as SerializedData<HashMap<Int, Bundle?>>
).serialized
}

// Auto DataBinding
binding = autoViewDataBinding()

Expand Down Expand Up @@ -101,15 +129,14 @@ abstract class CoreActivity <VDB: ViewDataBinding> : AppCompatActivity() {

startActivity(this)

if (withFinish) {
finish()
}
if (withFinish) finish()
}

runTransitionAnimation()
}

fun startAppSettings() {

startActivity(
Intent(
Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Expand All @@ -118,6 +145,7 @@ abstract class CoreActivity <VDB: ViewDataBinding> : AppCompatActivity() {
)
)
)

runTransitionAnimation()
}

Expand All @@ -144,4 +172,189 @@ abstract class CoreActivity <VDB: ViewDataBinding> : AppCompatActivity() {
protected fun binding(block: VDB.() -> Unit) = binding.apply {
block.invoke(this)
}

override fun onStart() {
super.onStart()

if (navHostFragmentIdCache != -1) {
attachDestinationChangeListener()
attachBackStackChangeListener()
}
}

private fun attachDestinationChangeListener() {

destinationChangeListener = NavController
.OnDestinationChangedListener { _, destination, arguments ->

if (destination.navigatorName == DIALOG_NAVIGATOR) {
wasPreviouslyShowingDialog = true

} else if (
destination.navigatorName == FRAGMENT_NAVIGATOR && wasPreviouslyShowingDialog
) {

wasPreviouslyShowingDialog = false

backStackChangeListener?.onBackStackChanged()
}

arguments?.getInt(FRAGMENT_REQUEST_CODE, -1)
?.takeIf {
it > -1
}
?.also {
pendingRequests[it] = null
}

}.also {
findNavController(navHostFragmentIdCache).addOnDestinationChangedListener(it)
}
}

private fun attachBackStackChangeListener() {

backStackChangeListener = FragmentManager.OnBackStackChangedListener {

supportFragmentManager.findFragmentById(navHostFragmentIdCache)?.let {

(it.childFragmentManager.primaryNavigationFragment as CoreFragment<*>).apply {
takeIf { coreFragment ->
coreFragment.pendingRequest > -1
}
?.takeIf { coreFragment ->
pendingRequests[coreFragment.pendingRequest] != null
}
?.also { coreFragment ->
coreFragment.onFragmentResult(
coreFragment.pendingRequest,
pendingRequests[coreFragment.pendingRequest]!!
)
}
?.also { coreFragment ->
pendingRequests.remove(coreFragment.pendingRequest)
}
}
}

}.also {
supportFragmentManager.findFragmentById(navHostFragmentIdCache)
?.childFragmentManager
?.addOnBackStackChangedListener(it)
}
}

internal fun setBundle(requestCode: Int, bundle: Bundle) {
pendingRequests[requestCode] = bundle
}

fun navigate(navDirection: NavDirections, requestCode: Int = -1) {
navigate(navDirection.actionId, navDirection.arguments, requestCode)
}

fun navigate(
navDirection: NavDirections,
navOptions: NavOptions?,
requestCode: Int = -1
) {
navigate(navDirection.actionId, navDirection.arguments, navOptions, null, requestCode)
}

fun navigate(
navDirection: NavDirections,
navigatorExtras: Navigator.Extras?,
requestCode: Int = -1
) {
navigate(navDirection.actionId, navDirection.arguments, null, navigatorExtras, requestCode)
}

fun navigate(@IdRes navDirection: Int, requestCode: Int) {
navigate(navDirection, null, requestCode)
}

fun navigate(@IdRes navDirection: Int, bundle: Bundle?, requestCode: Int) {
navigate(navDirection, bundle, null, requestCode)
}

fun navigate(
@IdRes navDirection: Int,
bundle: Bundle?,
navOptions: NavOptions?,
requestCode: Int
) {
navigate(navDirection, bundle, navOptions, null, requestCode)
}

fun navigate(
@IdRes navDirection: Int,
bundle: Bundle?,
navOptions: NavOptions?,
navigatorExtras: Navigator.Extras?,
requestCode: Int
) {
if (navHostFragmentIdCache == -1) return
supportFragmentManager.findFragmentById(navHostFragmentIdCache)?.let {
(it.childFragmentManager.primaryNavigationFragment as CoreFragment<*>).apply {
navigate(navDirection, bundle, navOptions, navigatorExtras, requestCode)
}
}
}

fun setNavHostFragmentId(@IdRes navHostId: Int) {
navHostFragmentIdCache = navHostId
reattach()
}

private fun reattach() {

if (navHostFragmentIdCache != -1) {
detachBackStackChangeListener()
detachDestinationChangeListener()
attachBackStackChangeListener()
attachDestinationChangeListener()
}
}

override fun onStop() {
super.onStop()

if (navHostFragmentIdCache != -1) {
detachBackStackChangeListener()
detachDestinationChangeListener()
}
}

private fun detachBackStackChangeListener() {
backStackChangeListener?.let {
supportFragmentManager.findFragmentById(
navHostFragmentIdCache
)?.childFragmentManager?.removeOnBackStackChangedListener(it)
}
}

private fun detachDestinationChangeListener() {
destinationChangeListener?.let {
findNavController(navHostFragmentIdCache)
.removeOnDestinationChangedListener(
it
)
}
}

override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)

outState.putSerializable(
PENDING_REQUESTS, SerializedData(pendingRequests)
)
}

companion object {

private const val PENDING_REQUESTS = "PENDING_REQUESTS"
private const val DIALOG_NAVIGATOR = "DIALOG"
private const val FRAGMENT_NAVIGATOR = "FRAGMENT"

internal const val FRAGMENT_REQUEST_CODE = "fragment:requestCode"
}
}
Loading

0 comments on commit 32fe714

Please sign in to comment.