如何让BottomNavigation重选时回到嵌套导航起始目的地?
实现底部导航重选时回到嵌套导航图的起始目的地
核心思路是利用Navigation组件的OnItemReselectedListener监听底部导航的重复点击事件,配合导航图中配置的Action,实现回到对应嵌套导航的起始页面。
1. 确认导航图的Action配置
你的navigation.xml中已经为navigation_nested3(notification嵌套导航图)配置了正确的返回Action,这个配置可以保留:
<action android:id="@+id/action_navigation_nested3_self" app:destination="@id/navigation_notifications" app:launchSingleTop="true" app:popUpTo="@id/navigation_notifications" app:popUpToInclusive="true"/>
popUpTo+popUpToInclusive="true":清除嵌套导航图内从起始页到当前页面的所有栈元素,确保回到纯净的起始页launchSingleTop="true":避免重复创建起始页实例,提升性能
如果需要给home、dashboard也实现相同功能,可在对应嵌套图中添加同款Action:
<!-- 给navigation_nested1添加返回起始页的Action --> <navigation android:id="@+id/navigation_nested1" app:startDestination="@id/navigation_home"> <fragment android:id="@+id/navigation_home" android:name="com.example.myvagtest.ui.home.HomeFragment" android:label="@string/title_home" tools:layout="@layout/fragment_home" /> <action android:id="@+id/action_navigation_nested1_self" app:destination="@id/navigation_home" app:launchSingleTop="true" app:popUpTo="@id/navigation_home" app:popUpToInclusive="true"/> </navigation> <!-- 给navigation_nested2添加返回起始页的Action --> <navigation android:id="@+id/navigation_nested2" app:startDestination="@id/navigation_dashboard"> <fragment android:id="@+id/navigation_dashboard" android:name="com.example.myvagtest.ui.dashboard.DashboardFragment" android:label="@string/title_dashboard" tools:layout="@layout/fragment_dashboard" /> <action android:id="@+id/action_navigation_nested2_self" app:destination="@id/navigation_dashboard" app:launchSingleTop="true" app:popUpTo="@id/navigation_dashboard" app:popUpToInclusive="true"/> </navigation>
2. 在MainActivity中设置重选监听
修改MainActivity,添加底部导航的重选监听逻辑,重复点击已选中的菜单项时触发回到起始页:
完整修改后的代码:
package com.example.myvagtest; import android.os.Bundle; import android.view.MenuItem; import com.google.android.material.bottomnavigation.BottomNavigationView; import com.google.android.material.navigation.NavigationBarView; import androidx.appcompat.app.AppCompatActivity; import androidx.navigation.NavController; import androidx.navigation.Navigation; import androidx.navigation.ui.AppBarConfiguration; import androidx.navigation.ui.NavigationUI; import com.example.myvagtest.databinding.ActivityMainBinding; import java.util.HashSet; import java.util.Set; public class MainActivity extends AppCompatActivity { private ActivityMainBinding binding; private NavController navController; private BottomNavigationView navView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = ActivityMainBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); navView = findViewById(R.id.nav_view); AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder( R.id.navigation_nested3,R.id.navigation_nested2,R.id.navigation_nested1).build(); navController = Navigation.findNavController(this, R.id.nav_host_fragment_activity_main); NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration); NavigationUI.setupWithNavController(navView, navController); // 初始化底部导航重选监听 setupBottomNavigationReselection(); } private void setupBottomNavigationReselection() { navView.setOnItemReselectedListener(new NavigationBarView.OnItemReselectedListener() { @Override public void onNavigationItemReselected(@NonNull MenuItem item) { int itemId = item.getItemId(); // 根据菜单项ID匹配对应嵌套图的返回Action if (itemId == R.id.navigation_nested1) { navController.navigate(R.id.action_navigation_nested1_self); } else if (itemId == R.id.navigation_nested2) { navController.navigate(R.id.action_navigation_nested2_self); } else if (itemId == R.id.navigation_nested3) { navController.navigate(R.id.action_navigation_nested3_self); } } }); } }
逻辑说明
OnItemReselectedListener:仅在用户点击当前已选中的底部菜单项时触发,不会干扰正常的导航切换行为- 导航Action的
popUpTo配置:确保嵌套导航图内的页面栈被清空,彻底回到起始页,避免栈内堆积无效页面 launchSingleTop="true":如果起始页已经在栈顶,不会重复创建新实例,减少内存消耗
内容的提问来源于stack exchange,提问作者Saulius Lipkevičius
相关产品推荐
相关产品推荐

