Navigation Drawer中Sign Out项无法跳转至Login页面求助
导航抽屉“Sign Out”点击无跳转解决方法
我希望实现导航抽屉(Navigation Drawer)中的“Sign Out”项点击后跳转至Login页面,代码无报错但功能失效,相关代码如下:
Homepage.java 代码
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = ActivityHomepageBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); setSupportActionBar(binding.appBarHomepage.toolbar); binding.appBarHomepage.fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) .setAction("Action", null).show(); } }); DrawerLayout drawer = binding.drawerLayout; NavigationView navigationView = binding.navView; navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() { @Override public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) { int id=menuItem.getItemId(); if (id == R.id.nav_Sign_out){ Intent intent = new Intent(Homepage.this, Login.class); startActivity(intent); } return true; } }); mAppBarConfiguration = new AppBarConfiguration.Builder(R.id.nav_dashboard, R.id.nav_profile, R.id.nav_orders, R.id.nav_recent_orders, R.id.nav_pending_deliveries, R.id.nav_cancelled_orders, R.id.nav_settings) .setOpenableLayout(drawer) .build(); NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_homepage); NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration); NavigationUI.setupWithNavController(navigationView, navController); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.homepage, menu); return true; } @Override public boolean onSupportNavigateUp() { NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_homepage); return NavigationUI.navigateUp(navController, mAppBarConfiguration) || super.onSupportNavigateUp(); }
Login.java 代码
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); textview = (TextView) findViewById(R.id.textViewSignUp); textview.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(Login.this,Register.class); startActivity(intent); } }); button = (Button) findViewById(R.id.btnLogin); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(Login.this,Homepage.class); startActivity(intent); } }); }
activity_main_drawer.xml 代码
<group android:id="@+id/menu_top" android:checkableBehavior="none"> <item android:id="@+id/nav_dashboard" android:icon="@drawable/ic_baseline_dashboard_24" android:title="@string/dashboard"> </item> <item android:id="@+id/nav_profile" android:icon="@drawable/ic_baseline_person_24" android:title="@string/profile" > </item> </group> <item android:id="@+id/nav_orders" android:title="@string/orders" > <menu> <item android:id="@+id/nav_menu_orders" android:title="@string/Orders" android:icon="@drawable/ic_orders" /> <item android:id="@+id/nav_recent_orders" android:title="@string/recent_orders" android:icon="@drawable/ic_recent" /> </menu> </item> <item android:id="@+id/nav_deliveries" android:title="@string/deliveries" > <menu> <item android:id="@+id/nav_pending_deliveries" android:title="@string/pending_deliveries" android:icon="@drawable/ic_pending_deliveries"/> <item android:id="@+id/nav_recent_deliveries" android:title="@string/recent_deliveries" android:icon="@drawable/ic_recent" /> </menu> </item> <item android:id="@+id/nav_cancelled_orders" android:icon="@drawable/ic_baseline_cancel_24" android:title="@string/cancelled_orders" > </item> <item android:id="@+id/nav_settings" android:icon="@drawable/ic_baseline_settings_24" android:title="@string/settings" > </item> <group android:id="@+id/nav_menu_bottom" android:checkableBehavior="none"> <item android:id="@+id/nav_Sign_out" android:icon="@drawable/ic_sign_out" android:title="@string/sign_out"> </item> </group>
问题原因
你手动设置的OnNavigationItemSelectedListener被NavigationUI.setupWithNavController(navigationView, navController)覆盖了。这行代码会自动给NavigationView绑定导航控制器的默认点击监听器,直接替换掉你之前写的逻辑,导致Sign Out的点击事件根本不会触发。
解决方法
调整代码顺序,先让NavigationUI完成默认导航绑定,再设置自定义监听器,同时在监听器中区分处理Sign Out和其他默认导航项:
修改Homepage.java中的导航相关代码为:
DrawerLayout drawer = binding.drawerLayout; NavigationView navigationView = binding.navView; // 先初始化导航控制器并完成默认配置 mAppBarConfiguration = new AppBarConfiguration.Builder(R.id.nav_dashboard, R.id.nav_profile, R.id.nav_orders, R.id.nav_recent_orders, R.id.nav_pending_deliveries, R.id.nav_cancelled_orders, R.id.nav_settings) .setOpenableLayout(drawer) .build(); NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_homepage); NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration); NavigationUI.setupWithNavController(navigationView, navController); // 重新设置自定义监听器,处理Sign Out逻辑 navigationView.setNavigationItemSelectedListener(item -> { int id = item.getItemId(); if (id == R.id.nav_Sign_out) { // 跳转Login页面,同时清除栈避免返回主页 Intent intent = new Intent(Homepage.this, Login.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); finish(); // 关闭当前Homepage drawer.closeDrawer(GravityCompat.START); // 关闭导航抽屉 return true; } // 其他导航项交给NavigationUI处理 return NavigationUI.onNavDestinationSelected(item, navController) || super.onOptionsItemSelected(item); });
额外优化
- 添加
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK)可以清除当前活动栈,用户从Login页返回时不会回到Homepage,符合退出登录的逻辑。 - 调用
drawer.closeDrawer(GravityCompat.START)在点击后关闭导航抽屉,提升用户体验。
内容的提问来源于stack exchange,提问作者NoobieMobileDev
相关产品推荐
相关产品推荐

