36

I'm currently using Android Navigation Architecture in my project. It has a feature that can launch any fragment with a shortcut. Currently I'm using NavController to navigate to desired destination when clicking at a shortcut. But when I clicked a shortcuts with multiple times, every time a new instance of the fragment will be created. So, my question is, Is there any way to only accept one instance of a fragment when navigate to it with NavController? I'm googling many times but found nothing. Thanks in advance.

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115

3 Answers3

1

Add a check before navigating to the destination as it would not add a new instance.

class A: AppCompatActivity {

    fun onCreate(...) {
        // ...While navigating
        if (navController.currentDestination?.id != desiredDestination?.id) {
            navController.navigate(desiredDestination)
        }
        // ...else do nothing
    }
}

Callback from NavController: https://developer.android.com/reference/androidx/navigation/NavController#addOnDestinationChangedListener(androidx.navigation.NavController.OnDestinationChangedListener)

Puneet Verma
  • 101
  • 5
0

You can use by navGraphViewModels delegate

The most important thing is to set id to your views in order to save state during config changes.This has not mentioned in official docs.

by default fragment navigation won't be saved during config changes(rotation and ...).

ViewModel will remain across config changes and you can save your state there then restore it.

Also check these links:

https://code.luasoftware.com/tutorials/android/android-jetpack-navigation-lost-state-after-navigation/

and

Android navigation component: how save fragment state

user16728174
  • 182
  • 1
  • 4
0

You can use safeOnClickListener instead of default onClickListener for capturing click on shortcut, so basically with safeOnClickListener you ignore all the click event for a given duration.

    class SafeClickListener(
        private var defaultInterval: Int = 2000,
        private val onSafeCLick: (View) -> Unit
    ) : View.OnClickListener {

        private var lastTimeClicked: Long = 0

        override fun onClick(v: View) {
            if (SystemClock.elapsedRealtime() - lastTimeClicked < defaultInterval) {
                return
            }
            lastTimeClicked = SystemClock.elapsedRealtime()
            onSafeCLick(v)
        }
    }

    fun View.setSafeOnClickListener(delay: Int = 2000, onSafeClick: (View) -> Unit) {
        val safeClickListener = SafeClickListener(delay) {
            onSafeClick(it)
        }
        setOnClickListener(safeClickListener)
    }
ritesh4302
  • 336
  • 1
  • 5
  • 11