我想在点击
BottomNavigationView
中的不同选项卡时弹出一个片段。
我在
BottomNavigationView
中有三个选项卡,其中第二个选项卡作为起始目的地。在第二个选项卡上,我可以搜索某些项目,来自后端的数据将显示在该堆栈中的另一个片段上,换句话说:
A - B - C (origin state)
D
A - B - C (state after search has been performed)
在后退按钮上单击此片段将被删除到原始状态
A - B - C
,但是如果搜索用户单击另一个选项卡A或C后,堆栈将保留D片段,并且在用户返回B选项卡后将显示D片段.
导航支持 xml
popUpInclusive
选项,但 BottomNavigationView
的默认导航未在 xml 中定义导航操作 - 它支持开箱即用。至少我还没有找到如何覆盖这种行为。
我可能会通过 OnItemViewSelectedListener
监听导航更改,但不清楚下一步如何继续。其他一些使用fragmentManager.replace()的解决方案看起来很难看。 navigateUp()
看起来更好,但我还没有设法将其正确应用到这个场景,这也引起了对处理导航组件的正确方法的担忧。
实现这种行为的正确方法是什么?我希望当用户导航到不同的选项卡时从堆栈中弹出我的搜索片段。
<?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/mobile_navigation"
app:startDestination="@+id/navigation_dashboard">
<fragment
android:id="@+id/navigation_home"
android:name="ru.home.government.screens.deputies.DeputiesFragment"
android:label="@string/title_deputies"
tools:layout="@layout/fragment_deputies">
<argument
android:name="EXTRA_NO_BOTTOM_VIEW"
app:argType="boolean"
android:defaultValue="false" />
<action
android:id="@+id/action_navigation_home_to_navigation_dashboard"
app:destination="@id/navigation_dashboard"
app:popUpTo="@+id/navigation_home"
app:popUpToInclusive="true" />
</fragment>
<fragment
android:id="@+id/navigation_dashboard"
android:name="ru.home.government.screens.laws.main.LawsMainFragment"
android:label="@string/title_laws"
tools:layout="@layout/fragment_laws" >
<action
android:id="@+id/action_navigation_dashboard_to_lawsFilteredFragment"
app:destination="@id/navigation_laws_filtered"
/>
<action
android:id="@+id/action_navigation_dashboard_to_navigation_home"
app:destination="@id/navigation_home"
app:popUpTo="@+id/navigation_dashboard"
app:popUpToInclusive="true"
/>
<action
android:id="@+id/action_navigation_dashboard_to_navigation_notifications"
app:destination="@id/navigation_notifications"
app:popUpTo="@+id/navigation_dashboard"
app:popUpToInclusive="true"
/>
</fragment>
<fragment
android:id="@+id/navigation_notifications"
android:name="ru.home.government.screens.tracker.TrackerFragment"
android:label="@string/title_tracker"
tools:layout="@layout/fragment_tracker">
<action
android:id="@+id/action_navigation_notifications_to_navigation_dashboard"
app:destination="@id/navigation_dashboard"
app:popUpTo="@+id/navigation_home"
app:popUpToInclusive="true" />
</fragment>
<fragment
android:id="@+id/navigation_laws_filtered"
android:name="ru.home.government.screens.laws.filter.LawsFilteredFragment"
android:label="@string/title_search"
tools:layout="@layout/fragment_law_filtered">
<argument
android:name="EXTRA_KEY"
app:argType="string"
android:defaultValue="false" />
<action
android:id="@+id/action_navigation_laws_filtered_to_navigation_home"
app:destination="@id/navigation_home"
app:popUpTo="@+id/navigation_dashboard"
app:popUpToInclusive="true" />
<action
android:id="@+id/action_navigation_laws_filtered_to_navigation_notifications"
app:destination="@id/navigation_notifications"
app:popUpTo="@+id/navigation_dashboard"
app:popUpToInclusive="true" />
</fragment>
</navigation>
这对我有用,我创建了一个包含 4 个片段的测试项目,就像你的情况一样,只有其他与后按有关的东西,你也应该处理它,我将在最后提供该代码
<?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/mobile_navigation"
app:startDestination="@+id/navigation_dashboard">
<fragment
android:id="@+id/navigation_home"
android:name="ru.home.government.screens.deputies.DeputiesFragment"
android:label="@string/title_deputies"
tools:layout="@layout/fragment_deputies">
<argument
android:name="EXTRA_NO_BOTTOM_VIEW"
app:argType="boolean"
android:defaultValue="false" />
<action
android:id="@+id/action_navigation_home_to_navigation_dashboard"
app:destination="@id/navigation_dashboard" />
</fragment>
<fragment
android:id="@+id/navigation_dashboard"
android:name="ru.home.government.screens.laws.main.LawsMainFragment"
android:label="@string/title_laws"
tools:layout="@layout/fragment_laws" >
<action
android:id="@+id/action_navigation_dashboard_to_lawsFilteredFragment"
app:destination="@id/navigation_laws_filtered"
/>
<action
android:id="@+id/action_navigation_dashboard_to_navigation_home"
app:destination="@id/navigation_home" />
<action
android:id="@+id/action_navigation_dashboard_to_navigation_notifications"
app:destination="@id/navigation_notifications"
app:popUpTo="@+id/navigation_dashboard"
app:popUpToInclusive="true"
/>
</fragment>
<fragment
android:id="@+id/navigation_notifications"
android:name="ru.home.government.screens.tracker.TrackerFragment"
android:label="@string/title_tracker"
tools:layout="@layout/fragment_tracker">
<action
android:id="@+id/action_navigation_notifications_to_navigation_dashboard"
app:destination="@id/navigation_dashboard"
app:popUpTo="@+id/navigation_home"
app:popUpToInclusive="true" />
</fragment>
<fragment
android:id="@+id/navigation_laws_filtered"
android:name="ru.home.government.screens.laws.filter.LawsFilteredFragment"
android:label="@string/title_search"
tools:layout="@layout/fragment_law_filtered">
<argument
android:name="EXTRA_KEY"
app:argType="string"
android:defaultValue="false" />
<action
android:id="@+id/action_navigation_laws_filtered_to_navigation_home"
app:destination="@id/navigation_home" />
<action
android:id="@+id/action_navigation_laws_filtered_to_navigation_notifications"
app:destination="@id/navigation_notifications" />
</fragment>
</navigation>
注意*** 如果您想从通知导航到返回主页,请不要执行此操作,否则请执行此步骤
以及后压处理
定义一个 backPressedCallback
private val backPressedCallback = object : OnBackPressedCallback(enabled = true) {
override fun handleOnBackPressed() {
if (navController.currentDestination?.id == R.id.navigation_notifications) {
navController.navigate(R.id.action_navigation_notifications_to_navigation_dashboard)
}
}
}
注册一下
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val navView: BottomNavigationView = findViewById(R.id.bottom_nav_bar)
navView.setupWithNavController(navController)
navController.addOnDestinationChangedListener { _, destination, _ ->
backPressedCallback.isEnabled = destination.id == R.id.navigation_notifications // enable back press custom handling only when notifications screen is on
}
onBackPressedDispatcher.addCallback(this, backPressedCallback)
}