我想用 BottomNavigationView 创建多个 NavHostFragment 来保存每个选项卡的状态。但是当我在选项卡之间切换时,navControllers 将返回到每个选项卡的 StartDestination。我遵循 https://github.com/moallemi/MultiNavHost 中的示例,这是我的代码: 1.主要活动:
public class MainActivity extends AppCompatActivity {
private BottomNavigationView bottomNavView;
private NavController currentController;
private AppBarConfiguration appBarConfiguration;
private TabManager tabManager;
private FrameLayout homeContainer, searchContainer, favoriteContainer, recentContainer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initControl();
}
@SuppressLint("ResourceType")
private void initControl() {
homeContainer= findViewById(R.id.homeContainer);
searchContainer= findViewById(R.id.searhContainer);
favoriteContainer= findViewById(R.id.favoriteContainer);
recentContainer= findViewById(R.id.recentContainer);
bottomNavView = findViewById(R.id.nav_view);
tabManager= new TabManager(this);
currentController= tabManager.getHomeController();
appBarConfiguration= new AppBarConfiguration.Builder(R.id.nav_home, R.id.nav_search,
R.id.nav_favorite, R.id.nav_recent).build();
NavigationUI.setupWithNavController(bottomNavView, currentController);
bottomNavView.setOnNavigationItemSelectedListener(item -> {
switchTab(item.getItemId());
return true;
});
bottomNavView.setSelectedItemId(R.id.nav_home);
}
@SuppressLint("RestrictedApi")
private void switchTab(int itemId) {
switch (itemId){
case R.id.nav_home:
currentController= tabManager.getHomeController();
setTabContainerInvisible();
homeContainer.setVisibility(View.VISIBLE);
NavigationUI.setupActionBarWithNavController(this, currentController, appBarConfiguration);
break;
case R.id.nav_search:
currentController= tabManager.getSearchController();
setTabContainerInvisible();
searchContainer.setVisibility(View.VISIBLE);
NavigationUI.setupActionBarWithNavController(this, currentController,
appBarConfiguration);
break;
case R.id.nav_favorite:
currentController= tabManager.getFavoriteController();
setTabContainerInvisible();
favoriteContainer.setVisibility(View.VISIBLE);
NavigationUI.setupActionBarWithNavController(this, currentController, appBarConfiguration);
break;
case R.id.nav_recent:
currentController= tabManager.getRecentController();
setTabContainerInvisible();
recentContainer.setVisibility(View.VISIBLE);
NavigationUI.setupActionBarWithNavController(this, currentController, appBarConfiguration);
break;
}
}
private void setTabContainerInvisible(){
homeContainer.setVisibility(View.INVISIBLE);
searchContainer.setVisibility(View.INVISIBLE);
favoriteContainer.setVisibility(View.INVISIBLE);
recentContainer.setVisibility(View.INVISIBLE);
}
2.TabManager
public class TabManager {
private MainActivity mainActivity;
public TabManager(MainActivity mainActivity) {
this.mainActivity = mainActivity;
}
@SuppressLint("ResourceType")
public NavController getHomeController(){
NavController homeController= Navigation.findNavController(mainActivity, R.id.home_nav_host_fragment);
NavGraph graph= homeController.getNavInflater().inflate(R.navigation.nav_graph);
graph.setStartDestination(R.id.nav_home);
homeController.setGraph(graph);
return homeController;
}
... setup another tab
3.NavGraph xml
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:showIn="@layout/app_bar_main">
<FrameLayout
android:id="@+id/homeContainer"
android:visibility="visible"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/home_nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="false"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</FrameLayout>
... <FrameLayout>... </FrameLayout>