Handling back button in Android Navigation Component

前端 未结 23 1278
遥遥无期
遥遥无期 2020-11-29 18:20

I\'d like to know how properly handle system back button action using Navigation Controller. In my app I have two fragments (for ex. fragment1 and fragment2) and I have an a

相关标签:
23条回答
  • 2020-11-29 19:14

    So, I created an interface

    public interface OnBackPressedListener {
        void onBackPressed();
    }
    

    And implemented it by all fragments that need to handle back button. In main activity I overrided onBackPressed() method:

    @Override
    public void onBackPressed() {
        final Fragment currentFragment = mNavHostFragment.getChildFragmentManager().getFragments().get(0);
        final NavController controller = Navigation.findNavController(this, R.id.nav_host_fragment);
        if (currentFragment instanceof OnBackPressedListener)
            ((OnBackPressedListener) currentFragment).onBackPressed();
        else if (!controller.popBackStack())
            finish();
    
    }
    

    So, If the top fragment of my Navigation host implements OnBackPressedListener interface, I call its onBackPressed() method, elsewhere I simply pop back stack and close application if the back stack is empty.

    0 讨论(0)
  • 2020-11-29 19:14

    I have searched through many threads and none of them work. Finally I found one:

    MainActivity.java

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        Toolbar mToolbar = findViewById(R.id.topAppBar);
        setSupportActionBar(mToolbar);
    }
    
    @Override
    public boolean onSupportNavigateUp() {
        navController.navigateUp();
        return super.onSupportNavigateUp();
    }
    

    MyFragment.java

    @Override
    public void onViewCreated(@NonNull final View view, @Nullable Bundle savedInstanceState) {
        Toolbar mToolbar = (MainActivity) getActivity().findViewById(R.id.topAppBar);
        mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Do something when uses presses back button (showing modals, messages,...)
                // Note that this will override behaviour of back button
            }
        });
    }
    
    @Override
    public void onStop() {
        // Reset back button to default behaviour when we leave this fragment
        Toolbar mToolbar = (MainActivity) getActivity().findViewById(R.id.topAppBar);
        mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mainActivity.onBackPressed();
            }
        });
    
        super.onStop();
    }
    
    0 讨论(0)
  • 2020-11-29 19:14

    just create an extension function to the fragment

    fun Fragment.onBackPressedAction(action: () -> Boolean) {
        requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, object :
            OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                this.isEnabled = action()
                if (!this.isEnabled) {
                    requireActivity().onBackPressed()
                }
            }
        })
    }
    

    and after in the fragment put the code into onCreateView (the action must return false to call the activity onBackPressed)

    onBackPressedAction { //do something }
    
    0 讨论(0)
  • 2020-11-29 19:15

    I written in main activity like this,

    override fun onSupportNavigateUp(): Boolean {
            return findNavController(R.id.my_nav_host_fragment).navigateUp(appBarConfiguration)
        }   
    
    0 讨论(0)
  • 2020-11-29 19:15

    The recommended method worked for me but after updating my library implementation 'androidx.appcompat:appcompat:1.1.0'

    Implement as below

     val onBackPressedCallback = object : OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                // Handle the back button event
            }
        }
        requireActivity().onBackPressedDispatcher.addCallback(this, onBackPressedCallback)
    

    using Kotlin

    0 讨论(0)
  • 2020-11-29 19:15

    Try this. I think this will help you.

    override fun onBackPressed() {
        when (mNavController.getCurrentDestination()!!.getId()) {
    
            R.id.loginFragment -> {
                onWarningAlertDialog(this, "Alert", "Do you want to close this application ?")
            }
            R.id.registerFragment -> {
                super.onBackPressed()
            }
        }
    }
    
    
    
    private fun onWarningAlertDialog(mainActivity: MainActivity, s: String, s1: String) {
    
            val dialogBuilder = AlertDialog.Builder(this)
            dialogBuilder.setMessage(/*""*/s1)
                    .setCancelable(false)
                    .setPositiveButton("Proceed", DialogInterface.OnClickListener { dialog, id ->
                        finish()
                    })
                    .setNegativeButton("Cancel", DialogInterface.OnClickListener { dialog, id ->
                        dialog.cancel()
                    })
    
            // create dialog box
            val alert = dialogBuilder.create()
            // set title for alert dialog box
            alert.setTitle("AlertDialogExample")
            // show alert dialog
            alert.show()
        }
    
    0 讨论(0)
提交回复
热议问题