在 Android 导航组件中处理 onBackPressed
Handle onBackPressed in Android Navigation Component
我在 Android 中使用导航组件实现了导航抽屉。我有 5 个片段,当我单击后退键时,我想返回到我的 HomeFragment
。目前,他们停留在 BackStack 上,不会转到我想要的片段,而是转到第一个片段。
这是我的 nav_graph
:
<?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"
app:startDestination="@id/setupFragment"
android:id="@+id/treasure_nav"
android:label="Pick a country">
<fragment android:id="@+id/homeFragment"
android:name="com.stavro_xhardha.pockettreasure.ui.home.HomeFragment"
android:label="Home"
tools:layout="@layout/fragment_home">
<action android:id="@+id/action_home_fragment_to_namesFragment2"
app:popUpTo="@id/homeFragment"
app:destination="@id/namesFragment"/>
<action android:id="@+id/action_home_fragment_to_quranFragment"
app:popUpTo="@id/homeFragment"
app:destination="@id/quranFragment"/>
<action android:id="@+id/action_homeFragment_to_tasbeehFragment"
app:popUpTo="@id/homeFragment"
app:destination="@id/tasbeehFragment"/>
<action android:id="@+id/action_homeFragment_to_galleryFragment"
app:popUpTo="@id/homeFragment"
app:destination="@id/galleryFragment"/>
<action android:id="@+id/action_homeFragment_to_newsFragment"
app:popUpTo="@id/homeFragment"
app:destination="@id/newsFragment"/>
<action android:id="@+id/action_homeFragment_to_settingsFragment"
app:popUpTo="@id/homeFragment"
app:destination="@id/settingsFragment"/>
</fragment>
<fragment
android:id="@+id/namesFragment"
android:name="com.stavro_xhardha.pockettreasure.ui.names.NamesFragment"
android:label="Names of Allah"
tools:layout="@layout/fragment_names"/>
<fragment
android:id="@+id/quranFragment"
android:name="com.stavro_xhardha.pockettreasure.ui.quran.QuranFragment"
android:label="Quran"
tools:layout="@layout/fragment_quran"/>
<fragment android:id="@+id/tasbeehFragment"
android:name="com.stavro_xhardha.pockettreasure.ui.tasbeeh.TasbeehFragment"
android:label="Tasbeeh"
tools:layout="@layout/fragment_tasbeeh"/>
<fragment android:id="@+id/galleryFragment"
android:name="com.stavro_xhardha.pockettreasure.ui.gallery.GalleryFragment"
android:label="Gallery"
tools:layout="@layout/fragment_gallery"/>
<fragment android:id="@+id/newsFragment"
android:name="com.stavro_xhardha.pockettreasure.ui.news.NewsFragment"
android:label="News"
tools:layout="@layout/fragment_news"/>
<fragment android:id="@+id/settingsFragment"
android:name="com.stavro_xhardha.pockettreasure.ui.settings.SettingsFragment"
android:label="Settings"
tools:layout="@layout/fragment_settings"/>
<fragment android:id="@+id/setupFragment"
android:name="com.stavro_xhardha.pockettreasure.ui.setup.SetupFragment"
android:label="Pick country"
tools:layout="@layout/fragment_setup">
<action android:id="@+id/action_setupFragment_to_homeFragment3"
app:destination="@+id/homeFragment"
app:launchSingleTop="true"
app:popUpTo="@+id/treasure_nav"
app:popUpToInclusive="true"/>
</fragment>
</navigation>
这是我的 MainActivity 中的 onBackPressed
(也是唯一的):
override fun onBackPressed() {
if (drawer_layout.isDrawerOpen(GravityCompat.START)) {
drawer_layout.closeDrawer(GravityCompat.START)
} else {
super.onBackPressed()
}
}
编辑:当我删除 super.onBackPressed()
并将其替换为:
findNavController(R.id.nav_host_fragment).popBackStack(R.id.homeFragment, false)
我达到了我想要的。唯一的问题是,当我在 homeFragment
时,我想结束应用程序,但我做不到。
如果您想在 HomeFragment 中按下返回键时关闭应用程序,只需指定将您导航到此目的地的最后一个操作的这些属性:
app:popUpToInclusive
到 true
app:popUpTo
到将您导航到此处的最后一个片段 (SetupFragment)(HomeFragment)
这意味着像这样更改您的代码:
<fragment android:id="@+id/setupFragment"
android:name="com.stavro_xhardha.pockettreasure.ui.setup.SetupFragment"
android:label="Pick country"
tools:layout="@layout/fragment_setup">
<action android:id="@+id/action_setupFragment_to_homeFragment3"
app:destination="@+id/homeFragment"
app:launchSingleTop="true"
app:popUpTo="@+id/setupFragment" // this line changes
app:popUpToInclusive="true" /> // and this requires too
</fragment>
如果我的理解是正确的,你想在导航流中的任何位置返回到 HomeFragment。对于这种情况,您可以尝试通过 addOnBackPressedCallback 在您的 Fragment 上注册 OnBackPressedCallback,然后调用 popBackStack 以导航到您的 HomeFragment。尝试将此添加到片段的 onViewCreated 中,它需要在 backpress 上返回到 HomeFragment:
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
navController = Navigation.findNavController(view);
requireActivity().addOnBackPressedCallback(getViewLifecycleOwner(), () -> {
navController.popBackStack(R.id.homeFragment, false);
});
return true;
});
我在 Android 中使用导航组件实现了导航抽屉。我有 5 个片段,当我单击后退键时,我想返回到我的 HomeFragment
。目前,他们停留在 BackStack 上,不会转到我想要的片段,而是转到第一个片段。
这是我的 nav_graph
:
<?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"
app:startDestination="@id/setupFragment"
android:id="@+id/treasure_nav"
android:label="Pick a country">
<fragment android:id="@+id/homeFragment"
android:name="com.stavro_xhardha.pockettreasure.ui.home.HomeFragment"
android:label="Home"
tools:layout="@layout/fragment_home">
<action android:id="@+id/action_home_fragment_to_namesFragment2"
app:popUpTo="@id/homeFragment"
app:destination="@id/namesFragment"/>
<action android:id="@+id/action_home_fragment_to_quranFragment"
app:popUpTo="@id/homeFragment"
app:destination="@id/quranFragment"/>
<action android:id="@+id/action_homeFragment_to_tasbeehFragment"
app:popUpTo="@id/homeFragment"
app:destination="@id/tasbeehFragment"/>
<action android:id="@+id/action_homeFragment_to_galleryFragment"
app:popUpTo="@id/homeFragment"
app:destination="@id/galleryFragment"/>
<action android:id="@+id/action_homeFragment_to_newsFragment"
app:popUpTo="@id/homeFragment"
app:destination="@id/newsFragment"/>
<action android:id="@+id/action_homeFragment_to_settingsFragment"
app:popUpTo="@id/homeFragment"
app:destination="@id/settingsFragment"/>
</fragment>
<fragment
android:id="@+id/namesFragment"
android:name="com.stavro_xhardha.pockettreasure.ui.names.NamesFragment"
android:label="Names of Allah"
tools:layout="@layout/fragment_names"/>
<fragment
android:id="@+id/quranFragment"
android:name="com.stavro_xhardha.pockettreasure.ui.quran.QuranFragment"
android:label="Quran"
tools:layout="@layout/fragment_quran"/>
<fragment android:id="@+id/tasbeehFragment"
android:name="com.stavro_xhardha.pockettreasure.ui.tasbeeh.TasbeehFragment"
android:label="Tasbeeh"
tools:layout="@layout/fragment_tasbeeh"/>
<fragment android:id="@+id/galleryFragment"
android:name="com.stavro_xhardha.pockettreasure.ui.gallery.GalleryFragment"
android:label="Gallery"
tools:layout="@layout/fragment_gallery"/>
<fragment android:id="@+id/newsFragment"
android:name="com.stavro_xhardha.pockettreasure.ui.news.NewsFragment"
android:label="News"
tools:layout="@layout/fragment_news"/>
<fragment android:id="@+id/settingsFragment"
android:name="com.stavro_xhardha.pockettreasure.ui.settings.SettingsFragment"
android:label="Settings"
tools:layout="@layout/fragment_settings"/>
<fragment android:id="@+id/setupFragment"
android:name="com.stavro_xhardha.pockettreasure.ui.setup.SetupFragment"
android:label="Pick country"
tools:layout="@layout/fragment_setup">
<action android:id="@+id/action_setupFragment_to_homeFragment3"
app:destination="@+id/homeFragment"
app:launchSingleTop="true"
app:popUpTo="@+id/treasure_nav"
app:popUpToInclusive="true"/>
</fragment>
</navigation>
这是我的 MainActivity 中的 onBackPressed
(也是唯一的):
override fun onBackPressed() {
if (drawer_layout.isDrawerOpen(GravityCompat.START)) {
drawer_layout.closeDrawer(GravityCompat.START)
} else {
super.onBackPressed()
}
}
编辑:当我删除 super.onBackPressed()
并将其替换为:
findNavController(R.id.nav_host_fragment).popBackStack(R.id.homeFragment, false)
我达到了我想要的。唯一的问题是,当我在 homeFragment
时,我想结束应用程序,但我做不到。
如果您想在 HomeFragment 中按下返回键时关闭应用程序,只需指定将您导航到此目的地的最后一个操作的这些属性:
app:popUpToInclusive
到true
app:popUpTo
到将您导航到此处的最后一个片段 (SetupFragment)(HomeFragment)
这意味着像这样更改您的代码:
<fragment android:id="@+id/setupFragment"
android:name="com.stavro_xhardha.pockettreasure.ui.setup.SetupFragment"
android:label="Pick country"
tools:layout="@layout/fragment_setup">
<action android:id="@+id/action_setupFragment_to_homeFragment3"
app:destination="@+id/homeFragment"
app:launchSingleTop="true"
app:popUpTo="@+id/setupFragment" // this line changes
app:popUpToInclusive="true" /> // and this requires too
</fragment>
如果我的理解是正确的,你想在导航流中的任何位置返回到 HomeFragment。对于这种情况,您可以尝试通过 addOnBackPressedCallback 在您的 Fragment 上注册 OnBackPressedCallback,然后调用 popBackStack 以导航到您的 HomeFragment。尝试将此添加到片段的 onViewCreated 中,它需要在 backpress 上返回到 HomeFragment:
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
navController = Navigation.findNavController(view);
requireActivity().addOnBackPressedCallback(getViewLifecycleOwner(), () -> {
navController.popBackStack(R.id.homeFragment, false);
});
return true;
});