15

I need some suggestions;

I'm experimenting with Navigation library. I have a fragment which has a webView. I want to check if it canGoBack and do so if it can, otherwise not interfere.

1. Interface approach: Since Navigation is handling transactions, I don't create an instance of my fragment manually anymore, which I can assign as a listener in activity.

1. Key listening: I really think it looks ugly and I don't think it's a generic solution, so I skip this one.

I need some opinions on how can it be done with Navigation library. When you try to get currentDestination from navController, it's NavigationDestination object which provides information about current fragment, such as label given in xml.

When I inspect fragmentManager, I see that backStack is empty & fragment transaction took place without a tag.

IMHO it wouldn't fit the concept of the library to do findFragment kind of operations to somewhat interact with current fragment, but I can't seem to find a way through with it at the moment. Any suggestions ?

Mel
  • 1,730
  • 17
  • 33

4 Answers4

11

I found a way to do it as before with interface or base fragment class.

in Activity:

override fun onBackPressed() {
    val f = currentFragment
    if (f !is BaseFragment || f.onBackPressed()) {
        if (!findNavController(R.id.nav_host_fragment).navigateUp()) {
            super.onBackPressed()
        }
    }
}

val currentFragment: Fragment?
    get() = nav_host_fragment.childFragmentManager.findFragmentById(R.id.nav_host_fragment)

in BaseFragment:

open fun onBackPressed() = true /*or false if you want to prevent navigation*/
AnoDest
  • 333
  • 1
  • 3
  • 13
4

We can directly handle OnBackPressed from any fragment

requireActivity().onBackPressedDispatcher
        .addCallback(viewLifecycleOwner, object: OnBackPressedCallback(true) {
        override fun handleOnBackPressed() {
            //Handle back event from any fragment 
        }
    })

Put above code in onViewCreated

0

OnBackPressedCallback can be used for this:

override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)
    activity?.addOnBackPressedCallback {
        Log.d(TAG, "handleOnBackPressed")
        //Your custom back behaviour
        return@addOnBackPressedCallback false
    }
}

Return false if you want the default back behaviour to execute. Return true to ignore it.

Sven
  • 1,648
  • 1
  • 21
  • 31
-1

I used this code to achieve onBackPressed in fragment.

override fun onAttach(context: Context) {
    super.onAttach(context)

    requireActivity().onBackPressedDispatcher.addCallback(
        this,
        object : OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                if (binding.edtText.length() > 0){
                    binding.edtText.text.clear()
                } else {
                    if(!findNavController().navigateUp()) {
                        if (isEnabled) {
                            isEnabled = false
                            requireActivity().onBackPressed()
                        }
                    }
                }
            }
        }
    )
}
Dilanka Laksiri
  • 408
  • 3
  • 12