Custom “navigate up” behavior for certain fragment using Navigation component

馋奶兔 提交于 2020-08-21 05:13:46

问题


I want to add custom up navigation from fragment using Navigation component

In my build.gradle(app) I use androidx.appcompat:appcompat:1.1.0-alpha04 dependency to have access to onBackPressedDispatcher from activity.

So I implemented OnBackPressedCallback in my fragment and registered callback to dispatcher:

requireActivity().onBackPressedDispatcher.addCallback(this)

I expected that pressing navigate up in toolbar will call it, but it doesn't. Pressing device's back button calls it as expected.

Is there a similar way to add some callback in fragment on navigate up action?

UPDATE

overridden methods onOptionsItemSelected and onSupportNavigateUp doesn't invoked on pressing up button in toolbar


回答1:


I found a solution

handleOnBackPressed() method invokes only on device's back button click. I wonder, why neither onOptionsItemSelected() nor onSupportNavigateUp() methods haven't been called on pressing "up button" in toolbar. And the answer is I used

NavigationUI.setupWithNavController(toolbar, navController, appBarConfiguration)

in activity to setup toolbar with navigation component. And that made toolbar responsive for work with navigation internally, pressing "up button" haven't invoked any of overridden methods in activity or fragments.

Instead should be used

NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration)

That will make actionBar responsive for navigation, thus I can use overridden functions onOptionsItemSelected() and onSupportNavigateUp() And best place (in my case) to add custom behavior on "up button" click for certain screen is

onSupportNavigateUp()

of hosted activity, like that

override fun onSupportNavigateUp(): Boolean {
        val navController = this.findNavController(R.id.mainNavHostFragment)
        return when(navController.currentDestination?.id) {
            R.id.destinationOfInterest -> {
                // custom behavior here 
                true
            }
            else -> navController.navigateUp()
        }
}

But worth to say, that if you want implement custom behavior directly in fragment, answer of @Enzokie should work like a charm




回答2:


You need to call onBackPressed() from onBackPressedDispatcher property. Assuming your Toolbar is properly setup you can use the code below in your Activity.

override fun onOptionsItemSelected(menuItem : MenuItem?) : Boolean {
    if (menuItem.getItemId() == android.R.id.home) {
        onBackPressedDispatcher.onBackPressed()
        return true // must return true to consume it here

    }
    return super.onOptionsItemSelected(menuItem)
}

on Fragment override

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

        //enable menu
        setHasOptionsMenu(true)

        requireActivity()
                .onBackPressedDispatcher
                .addCallback(this){
                   //true means that the callback is enabled
                    this.isEnabled = true
                    exitDialog() //dialog to conform exit
                }
    }

What this does is :

Trigger a call to the currently added OnBackPressedCallback callbacks in reverse order in which they were added. Only if the most false from its OnBackPressedCallback#handleOnBackPressed() will any previously added callback be called.

I am using AndroidX in my example therefore my import will look like

import androidx.appcompat.app.AppCompatActivity.




回答3:


This set up also works and you won't need to override onSupportNavigateUp in your activity:

NavigationUI.setupWithNavController(toolbar, navController, appBarConfiguration)
toolbar.setNavigationOnClickListener {
    if (navController.currentDestination?.id == R.id.destinationOfInterest) {
        // Custom behavior here
    } else {
        NavigationUI.navigateUp(navController, configuration)
    }
}

I prefer to set up the Toolbar since it will handle automatically the up navigation and open/close a DrawerLayout if you have one.




回答4:


Add click event to toolbar back button in this way

@Override
public boolean onOptionsItemSelected(MenuItem item) {
 switch (item.getItemId()) {
case android.R.id.home:
    // Toolbar back button pressed, do something you want    

default:
    return super.onOptionsItemSelected(item);
  }
}

Another way

  Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    // Title and subtitle
    toolbar.setNavigationOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            // Toolbar back button pressed, do something you want    
        }
    });


来源:https://stackoverflow.com/questions/55904485/custom-navigate-up-behavior-for-certain-fragment-using-navigation-component

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!