Android BottomNavigationView 与闪屏返回堆栈问题

Android BottomNavigationView with Splash Screen Back Stack Issue

所以我使用导航组件库设置了我的 BottomNavigationView(如 here),一切正常,每个选项卡都可以保留其返回堆栈。但是,如果我添加启动画面 (Fragment) 并且:

  1. 将其设置为起始目的地(popUpInclusive 已设置为真)
  2. 创建从 SplashFragment 到第一个选项卡 HomeFragment
  3. 的操作

然后所有选项卡不再保留它们的返回堆栈,而且导航变得奇怪:

Splash -> Home(第一个标签)-> Me(第二个标签)-> Home -> 按返回,它返回到我而不是退出应用程序。

PS:我使用单一 Activity 模式和单一导航图。

好的,感谢@ianhanniballake,我post这里是我的最终解决方案,关键是BottomNavigationView必须是其他[=21的起始目的地=] 喜欢登录或启动画面。


第 1 步。创建和设置启动布局和片段

  • SplashFragment 添加到导航图中。

  • 不需要从 HomeFragment -> SplashFragment 创建动作,除非你需要过渡动画

步骤 2. 设置 MainViewModel(共享 ViewModel

class MainViewModel : ViewModel() {
    private var _isFirstLaunch = true  //replace with the real condition in the future

    val isFirstLaunch: Boolean         //will be accessed by SplashFragment and HomeFragment
        get() = _isFirstLaunch

    fun updateIsFirstLaunch(isFirstLaunch: Boolean) {
        _isFirstLaunch = isFirstLaunch
    }
}

步骤 3. 设置 HomeFragment

class HomeFragment : Fragment() {
    private lateinit var binding: FragmentHomeBinding
    private lateinit var mainViewModel: MainViewModel  //shared ViewModel

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
        binding = DataBindingUtil.inflate(inflater, R.layout.fragment_home, container, false)
        mainViewModel = ViewModelProvider(requireActivity()).get(MainViewModel::class.java)

        if (mainViewModel.isFirstLaunch) {
            findNavController().navigate(R.id.splashFragment)   //no need action, unless you want transition animation
        }

        binding.goButton.setOnClickListener {
            findNavController().navigate(R.id.action_homeFragment_to_home2Fragment)
        }

        return binding.root
    }
}

步骤 4. 设置 SplashFragment

class SplashFragment : Fragment() {
    private lateinit var binding: FragmentSplashBinding
    private lateinit var mainViewModel: MainViewModel  //shared ViewModel

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
        binding = DataBindingUtil.inflate(inflater, R.layout.fragment_splash, container, false)
        mainViewModel = ViewModelProvider(requireActivity()).get(MainViewModel::class.java)

        binding.exitSplashButton.setOnClickListener {
            mainViewModel.updateIsFirstLaunch(false)  //update the condition

            findNavController().navigateUp()    //go back to HomeFragment
        } 

        requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) {
            requireActivity().finish()
        }

        return binding.root
    }
}

演示:https://youtu.be/AxiIsY6BtGg