自定义 BottomNavigationView 的行为

问题描述 投票:0回答:1

我想在点击

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>
android navigation bottomnavigationview
1个回答
0
投票

这对我有用,我创建了一个包含 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)
}
© www.soinside.com 2019 - 2024. All rights reserved.