Android BottomNavigationView 与闪屏返回堆栈问题
Android BottomNavigationView with Splash Screen Back Stack Issue
-
android
-
android-navigation
-
android-bottomnavigationview
-
android-navigation-graph
-
android-splashscreen
所以我使用导航组件库设置了我的 BottomNavigationView
(如 here),一切正常,每个选项卡都可以保留其返回堆栈。但是,如果我添加启动画面 (Fragment
) 并且:
- 将其设置为起始目的地(
popUpInclusive
已设置为真)
- 创建从 SplashFragment 到第一个选项卡 HomeFragment
的操作
然后所有选项卡不再保留它们的返回堆栈,而且导航变得奇怪:
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
}
}
android
android-navigation
android-bottomnavigationview
android-navigation-graph
android-splashscreen
所以我使用导航组件库设置了我的 BottomNavigationView
(如 here),一切正常,每个选项卡都可以保留其返回堆栈。但是,如果我添加启动画面 (Fragment
) 并且:
- 将其设置为起始目的地(
popUpInclusive
已设置为真) - 创建从 SplashFragment 到第一个选项卡 HomeFragment 的操作
然后所有选项卡不再保留它们的返回堆栈,而且导航变得奇怪:
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
}
}