【问题标题】:Dynamically change startDestination of nested navigation graph inside of a BottomNavigationView动态更改 BottomNavigationView 内嵌套导航图的 startDestination
【发布时间】:2021-10-01 08:02:44
【问题描述】:

我正在尝试更新我的应用以使用 BottomNavigationView。第一个选项卡包含一个带有加载微调器的HostFragment,它执行网络请求以确定哪个片段(HomeFragmentLockedFragment)应该显示在该选项卡中。

MainActivity 处理BottomNavigationView 的初始设置:

class MainActivity : AppCompatActivity() {

    private lateinit var navController: NavController
    private lateinit var appBarConfiguration: AppBarConfiguration

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val navHostFragment = supportFragmentManager.findFragmentById(
            R.id.nav_host_container
        ) as NavHostFragment
        navController = navHostFragment.navController

        val bottomNavigationView = findViewById<BottomNavigationView>(R.id.bottom_nav)
        bottomNavigationView.setupWithNavController(navController)

        appBarConfiguration = AppBarConfiguration(
            setOf(R.id.mainFragment)
        )
        setupActionBarWithNavController(navController, appBarConfiguration)
    }

我的主导航图如下所示:

<?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"
    android:id="@+id/nav_graph"
    app:startDestination="@+id/home">

    <include app:graph="@navigation/home"/>
    <include app:graph="@navigation/list"/>
    <include app:graph="@navigation/form"/>
</navigation>

主页图看起来像:

<?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"
    android:id="@+id/home"
    app:startDestination="@+id/hostFragment">

    <fragment
        android:id="@+id/hostFragment"
        android:name="com.example.android.bottomnav.homescreen.HostFragment"
        android:label="Host">
        <action
            android:id="@+id/action_hostFragment_to_homeFragment"
            app:destination="@id/homeFragment" />
        <action
            android:id="@+id/action_hostFragment_to_lockedFragment"
            app:destination="@id/lockedFragment" />
    </fragment>

    <fragment
        android:id="@+id/homeFragment"
        android:name="com.example.android.bottomnav.homescreen.HomeFragment"
        android:label="Home" />

    <fragment
        android:id="@+id/lockedFragment"
        android:name="com.example.android.bottomnav.homescreen.LockedFragment"
        android:label="Locked"/>
</navigation>

HostFragment get 显示正常并加载它的数据:

class HostFragment : Fragment() {
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_host, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        determineFragmentToShow()
    }

    private fun determineFragmentToShow() {
        lifecycleScope.launchWhenStarted {
            // mock network call to determine tab
            delay(1500)

            // show HomeFragment for the sake of the example, but note that
            // this would be dependent on the network call's result above
            findNavController().navigate(R.id.action_hostFragment_to_homeFragment)
        }
    }
}

它成功地将我们导航到HomeFragment

现在的问题是,每当我从HomeFragment 按下返回按钮时,它都会返回到HostFragment,而不是关闭应用程序。You can see the behavior in this video here.

我尝试在home.xml 中设置popUpTopopUpInclusive 标签,如下所示:

    <fragment
        android:id="@+id/hostFragment"
        android:name="com.example.android.bottomnav.homescreen.HostFragment"
        android:label="Host">
        <action
            android:id="@+id/action_hostFragment_to_homeFragment"
            app:destination="@id/homeFragment"
            app:popUpTo="@id/home"
            app:popUpToInclusive="true"/>
        <action
            android:id="@+id/action_hostFragment_to_lockedFragment"
            app:destination="@id/lockedFragment"
            app:popUpTo="@id/home"
            app:popUpToInclusive="true"/>
    </fragment>

当从HomeFragment 按下返回时,应用程序会关闭,但现在每次我切换到新选项卡时,它都会创建片段的新实例并将其添加到后台堆栈。然后按下后退按钮将向后遍历它们。 You can see that behavior in this video here.

那么如何更新嵌套导航图的起始目的地?

我正在使用最新的2.4.0-alpha10 导航组件,以便获得对多个后台堆栈的原生支持。非常感谢任何帮助!

【问题讨论】:

    标签: android android-fragments bottomnavigationview android-architecture-navigation


    【解决方案1】:

    我能够利用答案 here 来获得适合我的解决方案。

    HostFragment 中的determineFragmentToShow() 内部,我只是将findNavController().navigate(R.id.action_hostFragment_to_homeFragment) 替换为

    val navController = findNavController()
    val graph = navController.graph
    val walletGraph = graph.findNode(R.id.home) as NavGraph
    walletGraph.setStartDestination(R.id.homeFragment)
    navController.navigate(R.id.action_hostFragment_to_homeFragment)
    

    我仍然需要在此处包含 popUpTopopUpInclusive 标签

        <fragment
            android:id="@+id/hostFragment"
            android:name="com.example.android.bottomnav.homescreen.HostFragment"
            android:label="Host">
            <action
                android:id="@+id/action_hostFragment_to_homeFragment"
                app:destination="@id/homeFragment"
                app:popUpTo="@id/home"
                app:popUpToInclusive="true"/>
            <action
                android:id="@+id/action_hostFragment_to_lockedFragment"
                app:destination="@id/lockedFragment"
                app:popUpTo="@id/home"
                app:popUpToInclusive="true"/>
        </fragment>
    

    但这让我得到了我正在寻找的背部行为!

    【讨论】:

      猜你喜欢
      • 2020-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多