在导航组件的起始目标位置时如何处理后退按钮

时间:2018-06-19 21:21:32

标签: android-architecture-components android-navigation android-architecture-navigation

我已经开始使用新的导航组件,而且我真的在挖掘它!但是,我确实有一个问题-当我在图表的起始目标位置时,应该如何处理后退按钮?

这是我现在正在使用的代码:

findNavController(this, R.id.my_nav_host_fragment)
                .navigateUp()

当我在图表上的任何地方时,它工作得很好,它使我返回,但是当我在它的开始时,由于后备箱为空,应用程序崩溃了。

这对我来说很有意义,我只是不确定如何处理。

虽然我可以检查当前片段的ID是否与我知道作为图根的ID相同,但我正在寻找更优雅的解决方案,例如是否存在当前的bool标志该图是否为起始位置。

想法?

8 个答案:

答案 0 :(得分:4)

您不应覆盖“ onBackPressed”,而应覆盖“ onSupportNavigateUp”并将其放置在那里

findNavController(this, R.id.my_nav_host_fragment)
            .navigateUp()

根据官方文档: 您还将覆盖AppCompatActivity.onSupportNavigateUp()并调用NavController.navigateUp

https://developer.android.com/topic/libraries/architecture/navigation/navigation-implementing

答案 1 :(得分:3)

我有一个类似的场景,我想在到达起始目的地时完成活动,而在导航图更下方时执行常规的“ navigateUp”。我通过一个简单的扩展功能解决了这个问题:

fun NavController.navigateUpOrFinish(activity: AppCompatActivity): Boolean {
return if (navigateUp()) {
    true
} else {
    activity.finish()
    true
}

}

然后像这样调用它:

override fun onSupportNavigateUp() = 
        findNavController(R.id.nav_fragment).navigateUpOrFinish(this)

但是,我无法使用NavigationUI,因为无论何时我到达起始目的地,这都会隐藏后退箭头。所以代替:

NavigationUI.setupActionBarWithNavController(this, controller)

我手动控制了主页图标:

setSupportActionBar(toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setHomeAsUpIndicator(R.drawable.ic_navigation_back)

答案 2 :(得分:2)

在活动中覆盖onBackPressed,并检查当前目的地是否是起始目的地。

实际上看起来像这样:

@Override
public void onBackPressed() {
    if (Navigation.findNavController(this,R.id.nav_host_fragment)
            .getCurrentDestination().getId() == R.id.your_start_destination) {
        // handle back button the way you want here
        return;
    }
    super.onBackPressed();
}

答案 3 :(得分:0)

如果您指的是“根”导航图的开始(以防万一,您嵌套了导航图),那么至少不应该根据navigation principles来显示向上按钮。

答案 4 :(得分:0)

由于我的后退按钮正常工作,并且使用NavController.navigateUp()在启动目标后退按钮上崩溃了。我已将此代码更改为类似这样的代码。其他可能性是仅检查currentDestination == startDestination.id,但我想关闭Activity并返回其他Activity。

override fun onSupportNavigateUp() : Boolean {
        //return findNavController(R.id.wizard_nav_host_fragment).navigateUp()
        onBackPressed()
        return true
    }

答案 5 :(得分:0)

/** in your activity **/
private boolean doubleBackToExitPressedOnce = false;
        @RequiresApi(api = Build.VERSION_CODES.M)
        @Override
        public void onBackPressed() {
            int start = Navigation.findNavController(this, R.id.nav_host_fragment).getCurrentDestination().getId();
            if (start == R.id.nav_home) {
                if (doubleBackToExitPressedOnce) {
                    super.onBackPressed();
                    return;
                }
                this.doubleBackToExitPressedOnce = true;
                Toast.makeText(MainActivity.this, "Press back again to exits", Toast.LENGTH_SHORT).show();

                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        doubleBackToExitPressedOnce = false;
                    }
                }, 2000);
            } else {
                super.onBackPressed();
            }
        }

答案 6 :(得分:0)

只需在后退按钮Onclick中调用它

hongkongstocks <- structure(list(Date = structure(c(1590399000, 1590399300, 1590399600, 
1590399900, 1590400200, 1590400500, 1590400800, 1590401100, 1590401400, 
1590402000, 1590402300, 1590402600, 1590403200, 1590403500, 1590403800, 
1590404100, 1590404400, 1590404700, 1590405000, 1590405300, 1590405600, 
1590406200, 1590406800, 1590407100, 1590407400, 1590408000, 1590411900, 
1590412200, 1590412500, 1590412800, 1590413100, 1590413400, 1590413700, 
1590414600, 1590414900, 1590415200, 1590415500, 1590415800, 1590416100, 
1590416700, 1590417000, 1590417300, 1590417600, 1590417900, 1590418200, 
1590418500, 1590418800, 1590419100, 1590419400, 1590419700, 1590421200, 
1590421500, 1590421800, 1590422100, 1590422400, 1590422700, 1590485700, 
1590486000, 1590486300, 1590486600, 1590486900, 1590487200, 1590487500, 
1590487800, 1590488100, 1590488400, 1590488700, 1590489600, 1590490200, 
1590490500, 1590490800, 1590491100, 1590491400, 1590491700, 1590492000, 
1590492900, 1590493200, 1590494100, 1590498300, 1590498600, 1590498900, 
1590499200, 1590499800, 1590500100, 1590500400, 1590500700, 1590501000, 
1590501300, 1590501600, 1590501900, 1590502200, 1590502800, 1590503100, 
1590503400, 1590503700, 1590504000, 1590504300, 1590504600, 1590505200, 
1590506400, 1590507900, 1590508500), tzone = "UTC", class = c("POSIXct", 
"POSIXt")), Hang.Seng = c(100, 98.28, 98.46, 99.11, 99.74, 100.04, 
99.63, 99.77, 99.34, 99.37, 99.06, 99.13, 98.76, 98.72, 98.62, 
98.74, 98.64, 98.71, 98.93, 99.23, 98.99, 99.09, 99.02, 99.05, 
99.04, 99, 99.24, 99.19, 99.27, 99.32, 99.3, 99.33, 99.49, 99.26, 
99.21, 99.35, 99.53, 99.48, 99.51, 99.5, 99.57, 99.61, 99.76, 
99.75, 99.83, 99.97, 100.08, 99.96, 99.88, 99.87, 99.94, 99.98, 
99.99, 100.06, 100.12, 100.1, 101.41, 101.78, 102.05, 101.83, 
101.6, 101.82, 101.77, 101.92, 101.9, 101.98, 101.97, 101.86, 
101.61, 101.79, 101.8, 101.93, 101.99, 101.84, 101.74, 101.85, 
101.88, 101.94, 102.18, 102.09, 102.01, 102.02, 101.95, 101.96, 
102.06, 102.12, 102.1, 102.22, 102.17, 102.26, 102.23, 102.24, 
102.27, 102.3, 102.39, 102.36, 102.34, 102.25, 102.21, 102.13, 
102.04, 102.14)), class = c("spec_tbl_df", "tbl_df", "tbl", "data.frame"
), row.names = c(NA, -102L), spec = structure(list(cols = list(
    Date = structure(list(), class = c("collector_character", 
    "collector")), `Hang Seng` = structure(list(), class = c("collector_double", 
    "collector"))), default = structure(list(), class = c("collector_guess", 
"collector")), skip = 1), class = "col_spec"))

答案 7 :(得分:0)

在Jetpack Navigation Componenet中,如果要在弹出片段时执行某些操作,则需要覆盖以下功能。

  1. 在片段中添加OnBackPressedCallback可以在底部的系统导航栏中按向后时运行特殊操作。

     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
    
         onBackPressedCallback = object : OnBackPressedCallback(true) {
             override fun handleOnBackPressed() {
                 //perform your operation and call navigateUp
                findNavController().navigateUp()
             }
         }
     requireActivity().onBackPressedDispatcher.addCallback(onBackPressedCallback)
     }
    
  2. 在片段中添加onOptionsItemMenu,以处理应用程序左上角出现的向后箭头按下。

     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
         super.onViewCreated(view, savedInstanceState)
    
         setHasOptionsMenu(true)
     }
    
    override fun onOptionsItemSelected(item: MenuItem): Boolean {
       if (item.itemId == android.R.id.home) {
           //perform your operation and call navigateUp
           findNavController().navigateUp()
           return true
       }
       return super.onOptionsItemSelected(item)
    }
    
  3. 如果在主机片段上按back时没有特殊代码可运行,请在Activity中使用onSupportNavigateUp。

     override fun onSupportNavigateUp(): Boolean {
       if (navController.navigateUp() == false){
         //navigateUp() returns false if there are no more fragments to pop
         onBackPressed()
       }
       return navController.navigateUp()
     }
    

请注意,如果片段包含onOptionsItemSelected(),则不会调用onSupportNavigateUp()