使用Android Navigation组件拦截返回导航

3
我试图拦截Android应用程序上的后退导航,以便在退出当前片段/活动之前运行一些代码。该应用程序使用Android Navigation Component,连接到底部导航栏和工具栏。当堆栈不为空时,工具栏将显示返回按钮。我想要实现的是,在退出片段之前显示一个自定义对话框,询问用户是否要保存数据。我的片段包含几个EditText字段和一个保存按钮,应按下该按钮将数据保存到存储库中。如果用户没有这样做,则在返回时应显示弹出窗口。我已经使用"OnBackPressedCallback"拦截了Android返回按钮,但工具栏返回按钮仍将关闭片段。有没有办法拦截两种方法(通过工具栏按钮返回和通过Android返回按钮返回)?谢谢。
3个回答

3
你可以查看 NavigationUI.setupWithNavController(toolbar, navController, appBarConfiguration) 的代码,这将向你展示工具栏的向上导航是如何实现的。
以下是我的解决方案:
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    // default toolbar setup with navigation components
    final NavController navController = Navigation.findNavController( view );
    final AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder( navController.getGraph() ).build();
    NavigationUI.setupWithNavController( toolbar, navController, appBarConfiguration );

    // own changes like icon and dialog
    toolbar.setNavigationIcon( R.drawable.ic_close_24 );
    toolbar.setNavigationOnClickListener( v -> new AlertDialog.Builder( requireContext() )
        .setMessage( R.string.abort_editing )
        .setPositiveButton( R.string.dialog_button_close, (dialog, whichButton) -> NavigationUI.navigateUp( navController, appBarConfiguration ) )
        .setNegativeButton( R.string.dialog_button_cancel, null )
        .show() );
}

按预期工作,但是否也有一种方法可以摆脱NavigationOnClickListener? 我有一个设置,在其中我只需要拦截特定片段的UP导航。 当我在一个片段中设置了setNavigationOnClickListener()并导航到另一个片段时,动作仍然会被消耗。 - Romain Scherfflein
我为此找到了另一个解决方案,我添加了一个新的答案。 - Romain Scherfflein

2

我会试一下!谢谢 :) - Iscle

1
我有一个类似的问题,但我的设置中还有一个抽屉菜单。我需要仅在某个特定片段中拦截“向上”导航操作。另外,事实证明,一旦你添加了NavigationOnCLickListener,就无法摆脱它。所以这不是一个选项。
对我有效的方法是,在完成所有导航工作后将工具栏设置为SupportActionBar。
现在,“向上”操作事件出现在onOptionItemSelected()中,在这里我可以使用NavController.currentDestination来检查我当前所在的片段,然后决定是否打开抽屉、向上导航(或其他地方)或者什么都不做。
// in Activity.onCreate()
// do your setup of Navigation UI

setSupportActionBar(toolbar)

// add (it won't work without)

override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        return super.onCreateOptionsMenu(menu)
}

// and then

override fun onOptionsItemSelected(item: MenuItem): Boolean {

        when (navController?.currentDestination?.id) {
            R.id.dontAllowUpNavigationFragment -> { }
            in topLevelDestinationIds -> { binding.drawerLayout.open() }
            else -> { navController?.navigateUp() }
        }
        return true
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接