我有一个底部导航视图,该视图已在androidx导航中实现,但问题是它显示了
的错误java.lang.IllegalStateException: Fragment already added: BaseFragment{27d5b00 (2156a830-7756-4fc9-bc63-7c6f3d6705f0) id=0x7f08008c android:switcher:2131230860:0}
我有一个基本片段,可提供不同片段的视图
class MainActivity : AppCompatActivity(),
ViewPager.OnPageChangeListener,
BottomNavigationView.OnNavigationItemReselectedListener,
BottomNavigationView.OnNavigationItemSelectedListener {
// overall back stack of containers
private val backStack = Stack<Int>()
// list of base destination containers
private val fragments = listOf(
BaseFragment.newInstance(R.layout.content_home_base, R.id.toolbar_home, R.id.nav_host_home),
BaseFragment.newInstance(R.layout.content_library_base, R.id.toolbar_library, R.id.nav_host_library),
BaseFragment.newInstance(R.layout.content_settings_base, R.id.toolbar_settings, R.id.nav_host_settings))
// map of navigation_id to container index
private val indexToPage = mapOf(0 to R.id.home, 1 to R.id.library, 2 to R.id.settings)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// setup main view pager
main_pager.addOnPageChangeListener(this)
main_pager.adapter = ViewPagerAdapter()
main_pager.post(this::checkDeepLink)
main_pager.offscreenPageLimit = fragments.size
// set bottom nav
bottom_nav.setOnNavigationItemSelectedListener(this)
bottom_nav.setOnNavigationItemReselectedListener(this)
// initialize backStack with elements
if (backStack.empty()) backStack.push(0)
}
/// BottomNavigationView ItemSelected Implementation
override fun onNavigationItemSelected(item: MenuItem): Boolean {
val position = indexToPage.values.indexOf(item.itemId)
if (main_pager.currentItem != position) setItem(position)
return true
}
override fun onNavigationItemReselected(item: MenuItem) {
val position = indexToPage.values.indexOf(item.itemId)
val fragment = fragments[position]
fragment.popToRoot()
}
override fun onBackPressed() {
val fragment = fragments[main_pager.currentItem]
val hadNestedFragments = fragment.onBackPressed()
// if no fragments were popped
if (!hadNestedFragments) {
if (backStack.size > 1) {
// remove current position from stack
backStack.pop()
// set the next item in stack as current
main_pager.currentItem = backStack.peek()
} else super.onBackPressed()
}
}
/// OnPageSelected Listener Implementation
override fun onPageScrollStateChanged(state: Int) {}
override fun onPageScrolled(p0: Int, p1: Float, p2: Int) {}
override fun onPageSelected(page: Int) {
val itemId = indexToPage[page] ?: R.id.home
if (bottom_nav.selectedItemId != itemId) bottom_nav.selectedItemId = itemId
}
private fun setItem(position: Int) {
main_pager.currentItem = position
backStack.push(position)
}
private fun checkDeepLink() {
fragments.forEachIndexed { index, fragment ->
val hasDeepLink = fragment.handleDeepLink(intent)
if (hasDeepLink) setItem(index)
}
}
inner class ViewPagerAdapter : FragmentPagerAdapter(supportFragmentManager) {
override fun getItem(position: Int): Fragment = fragments[position]
override fun getCount(): Int = fragments.size
}
}
基本片段类:
class BaseFragment: Fragment() {
private val defaultInt = -1
private var layoutRes: Int = -1
private var toolbarId: Int = -1
private var navHostId: Int = -1
private val appBarConfig = AppBarConfiguration(rootDestinations)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
layoutRes = it.getInt(KEY_LAYOUT)
toolbarId = it.getInt(KEY_TOOLBAR)
navHostId = it.getInt(KEY_NAV_HOST)
} ?: return
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment
return if (layoutRes == defaultInt) null
else inflater.inflate(layoutRes, container, false)
}
override fun onStart() {
super.onStart()
// return early if no arguments were parsed
if (toolbarId == defaultInt || navHostId == defaultInt) return
// setup navigation with toolbar
val toolbar = requireActivity().findViewById<Toolbar>(toolbarId)
val navController = requireActivity().findNavController(navHostId)
NavigationUI.setupWithNavController(toolbar, navController, appBarConfig)
// NavigationUI.setupWithNavController(toolbar,navController)
}
fun onBackPressed(): Boolean {
return requireActivity()
.findNavController(navHostId)
.navigateUp(appBarConfig)
}
fun popToRoot() {
val navController = requireActivity().findNavController(navHostId)
navController.popBackStack(navController.graph.startDestination, false)
}
fun handleDeepLink(intent: Intent) = requireActivity().findNavController(navHostId).handleDeepLink(intent)
companion object {
private const val KEY_LAYOUT = "layout_key"
private const val KEY_TOOLBAR = "toolbar_key"
private const val KEY_NAV_HOST = "nav_host_key"
fun newInstance(layoutRes: Int, toolbarId: Int, navHostId: Int) = BaseFragment().apply {
arguments = Bundle().apply {
putInt(KEY_LAYOUT, layoutRes)
putInt(KEY_TOOLBAR, toolbarId)
putInt(KEY_NAV_HOST, navHostId)
}
}
}
}
我先尝试清空堆栈,但那没有用,我的三个viewpager元素/片段都有三个navgraphs。
答案 0 :(得分:2)
我们恢复到2.1.0(导航库),并且再次正常工作
答案 1 :(得分:1)
错误与导航库不太相关。这很可能是片段的错误本身。尝试在不使用导航的情况下在空活动中测试该片段。
导航库以某种方式错误地处理了错误。
p.s。就我而言,这只是布局文件中视图的ID缺失。
答案 2 :(得分:0)
感谢支持,我找到了为每个页面创建不同导航图的解决方案。