[英]Jetpack Navigation Component handle navigation controller with Bottom Navigation and it's Back Stack navigation
您好,我正在開發一個應用程序,但我一直停留在導航視圖中的導航上。
示例我有活動,在里面我定義了導航主機控制器,如下所示
setSupportActionBar(mMainToolbar);
mAppBarConfiguration = new AppBarConfiguration.Builder(
R.id.homeFragment, R.id.questionBankFragment,
R.id.testFragment, R.id.dailyHuntFragment,
R.id.liveClassesFragment)
.setOpenableLayout(mMainDrawerLayout)
.build();
View mNavigationViewHeaderView = mNavigationView.getHeaderView(0);
mNavHostFragment = getSupportFragmentManager().findFragmentById(R.id.nav_host_fragment);
mNavController = Navigation.findNavController(this, R.id.nav_host_fragment);
NavigationUI.setupActionBarWithNavController(this, mNavController, mAppBarConfiguration);
NavigationUI.setupWithNavController(mNavigationView, mNavController);
NavigationUI.setupWithNavController(mMainToolbar, mNavController, mAppBarConfiguration);
NavigationUI.setupWithNavController(mBottomNavigationView, mNavController);
mNavController.addOnDestinationChangedListener((controller, destination, arguments) -> {
switch (destination.getId()) {
case R.id.homeFragment:
case R.id.questionBankFragment:
mMainToolbar.setVisibility(View.VISIBLE);
mBottomNavigationView.setVisibility(View.VISIBLE);
setStatusBarColor(getResources().getColor(R.color.colorPrimaryDark));
setDrawerLocked(false);
break;
case R.id.welcomeFragment:
case R.id.loginFragment:
mMainToolbar.setVisibility(View.GONE);
mBottomNavigationView.setVisibility(View.GONE);
setStatusBarColor(Color.WHITE);
setDrawerLocked(true);
break;
case R.id.customModuleFragment:
case R.id.createCustomModuleOneFragment:
case R.id.createCustomModuleTwoFragment:
mBottomNavigationView.setVisibility(View.GONE);
setDrawerLocked(true);
break;
case R.id.logoutFragment:
new AppSharedPreference(MainActivity.this).clearAllData();
Intent intent = new Intent(getApplicationContext(), UserAuthanticationActivity.class);
startActivity(intent);
finish();
break;
}
});
它工作正常。 但現在我必須處理我無法理解的后堆棧導航。
我的問題是假設我是底部導航有 4 個菜單。 家,狩獵,Qbank,考試。
我被選為Qbank。 Qbank 有 5 個片段 A、B、C、D、E。現在我已經開始遍歷片段 A -> BB -> CC -> D
現在我可以選擇在哪里導航回到直接 A 喜歡。 當前位置是 D
D - > A
但是我如何回到 A 並清除我遍歷的堆棧 A -> B -> C -> D 我想清除這個,就像我想從 A 重新開始一樣。
我如何使用 Jetpack 導航組件實現這一目標。
我嘗試了直接導航或彈出堆棧導航,但它不起作用它給了我錯誤,就像我直接導航到
java.lang.IllegalStateException: View androidx.core.widget.NestedScrollView{98060fe VFED..... ......ID 0,0-0,0} does not have a NavController set
at androidx.navigation.Navigation.findNavController(Navigation.java:84)
at app.technotech.koncpt.McqTestFragment$2.onClick(McqTestFragment.java:232)
at android.view.View.performClick(View.java:7201)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:992)
at android.view.View.performClickInternal(View.java:7170)
at android.view.View.access$3500(View.java:806)
at android.view.View$PerformClick.run(View.java:27562)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7682)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:516)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
我不知道如何處理這個導航。請幫助解決這個我的解決方案
提前致謝。
如果這是您的起點或想要的目的地,您可以檢查當前導航目的地並彈出包容性
if (navController.currentDestination.id == navController.graph.YOUR_PREFERED_DESTIONATION) {
navController.popBackStack(
navController.graph.YOUR_PREFERED_DESTIONATION, true
)
}else {
navController.navigate(R.id.other_destination)
}
使用popUpTo從 backstack 中刪除先前 Fragment 的實例,並使用popUpToInclusive刪除A Fragment 的第一個實例,否則您的堆棧中將有兩個A Fragment實例:
來自Android官方文檔的演示代碼:
導航圖 XML 視圖:
<fragment
android:id="@+id/c"
android:name="com.example.myapplication.C"
android:label="fragment_c"
tools:layout="@layout/fragment_c">
<action
android:id="@+id/action_d_to_a"
app:destination="@id/a"
app:popUpTo="@+id/a"
app:popUpToInclusive="true"/>
您應該為每個底部導航項使用不同的導航圖。
這樣每個底部菜單項都有自己的圖表和自己的起始目的地。 所以按照這個導航路徑
A -> BB -> CC -> D 並添加以下代碼-
<action
android:id="@+id/action_d_to_a"
app:destination="@id/a"
app:popUpTo="@+id/a"
app:popUpToInclusive="true"/>
您可以彈出片段 A,這將是底部菜單項的起始目的地,並且您不會收到有關 NavController 目的地的錯誤。
我嘗試用以下示例和代碼進一步解釋-
我們有三個菜單項,即儀表板、查找和選項,在主要活動中,我將使用以下代碼來設置底部導航-
private void setupBottomNavigation() {
BottomNavigationView bottomNavigationView = (BottomNavigationView) findViewById(R.id.bottom_nav_view);
bottomNavigationView.setItemIconTintList(null);
List<Integer> navGraphList = new ArrayList<>();
navGraphList.add(R.navigation.dashboard_navigation);
navGraphList.add(R.navigation.find_navigation);
navGraphList.add(R.navigation.options_navigation);
LiveData<NavController> navControllerLiveData = new NavigationExtensions().setupWithNavController(
bottomNavigationView
, navGraphList
, getSupportFragmentManager()
, R.id.fragment_container, getIntent()
);
currentNavController = navControllerLiveData;
}
R.navigation.dashboard_navigation , R.navigation.find_navigation和R.navigation.options_navigation將導航文件如下-
儀表板_導航.xml
<?xml version="1.0" encoding="utf-8"?>
<navigation 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:id="@id/dashboard_navigation"
app:startDestination="@id/dashboardFragment">
<fragment
android:id="@+id/dashboardFragment"
android:name="your.package.DashboardFragment"
android:label=""
tools:layout="@layout/fragment_dashboard" >
</fragment>
<fragment
//add other fragment to this graph
</fragment>
<navigation>
活動_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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="match_parent"
android:id="@+id/coordinatorLayout_main"
android:background="?android:attr/colorBackground"
tools:context=".MainActivity">
<FrameLayout
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="?attr/actionBarSize" />
<com.google.android.material.bottomnavigation.BottomNavigationView
app:itemTextColor="@drawable/bottom_nav_selector"
android:id="@+id/bottom_nav_view"
android:layout_width="match_parent"
app:itemRippleColor="?colorPrimary"
app:labelVisibilityMode="labeled"
android:layout_height="?attr/actionBarSize"
android:layout_gravity="bottom"
app:menu="@menu/bottom_nav_menu"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
bottom_nav_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/dashboard_navigation"
android:icon="@drawable/dashboard_icon_selector"
android:title="@string/dashboardTitle" />
<item
android:id="@+id/find_navigation"
android:icon="@drawable/find_icon_selector"
android:title="@string/findTitle" />
<item
android:id="@+id/options_navigation"
android:icon="@drawable/setting_icon_selector"
android:title="@string/optionTitle" />
</menu>
確保菜單項 id 與導航圖的 id 匹配。 作為檢查儀表板,我使用菜單項 id 作為 android:id="@+id/dashboard_navigation" 這是相同的 id,用於dashboard_navigation.xml 圖形
您還必須使用谷歌本身提供的導航擴展(在 Kotlin 中) 。
要獲取有關使用多個導航圖的更多信息,請單擊此處
如果您想了解如何在 Java 代碼中使用 Navigatin 擴展文件,請在此處查看我的回答。
快樂編碼!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.