片段replace()的操作方式与remove()+ add()

时间:2019-04-27 12:36:21

标签: android android-fragments kotlin

根据Android docs

  

replace()本质上与对所有调用remove(Fragment)相同   当前添加的片段与相同   containerViewId,然后使用相同的内容添加(int,Fragment,String)   这里给出的论点。

但是我的代码另有说明。

我的应用有1个活动和多个片段。它还具有一个BottomNavigationView,其中包含3个标签(选项,游戏,排行榜)。

初始化MainActivity时,会将3个片段添加到容器FrameLayout MainActivity中。添加后,立即隐藏了2个片段,在屏幕上显示了1个(开始的片段)。

MainActivity.kt

override fun onCreate(savedInstanceState: Bundle?) {
    val transaction = supportFragmentManager.beginTransaction()
    transaction.add(R.id.fragment_layout, firstFragment, "Opening")
    transaction.add(R.id.fragment_layout, OptionsFragment(), "Options")
    transaction.add(R.id.fragment_layout,LeaderboardsFragment(), "Leaderboards")
    transaction.commitNow()
    val transaction2 = supportFragmentManager.beginTransaction()
    val options: androidx.fragment.app.Fragment = supportFragmentManager.findFragmentByTag("Options")!!
    val leaderboards: androidx.fragment.app.Fragment = supportFragmentManager.findFragmentByTag("Leaderboards")!!
    transaction2.hide(options)
    transaction2.hide(leaderboards)
    transaction2.commitNow()
}

从现在开始,不是OptionsFragment()LeaderboardsFragment()的每个片段都通过replace()换出。

OpeningFragment.kt

transaction?.replace(R.id.fragment_layout, playerDetailsFragment, "Add Player")
transaction?.commit()
gameString = "Add Player"
通过从底部导航中选择

OptionsFragment()LeaderboardsFragment()使其可见,然后隐藏除选定的片段之外的所有其他片段(例如,如果从底部导航中选择“选项”,则每个片段除了OptionsFragment())外,其他所有内容都被隐藏。

MainActivity.kt

override fun onNavigationItemSelected(item: MenuItem): Boolean {
    val fragmentTags = arrayListOf("Opening", "Leaderboards", "Options", "Add Player", "Question", "Location", "Game Over")
    val transaction = supportFragmentManager.beginTransaction()
    val selectedFragmentTag = when (item.itemId) {
        R.id.action_leaderboards -> "Leaderboards"
        R.id.action_options -> "Options"
        else -> {
            gameString 
        }
    }
    // Selected Fragment
    val selectedFragment: androidx.fragment.app.Fragment? = supportFragmentManager.findFragmentByTag(selectedFragmentTag)
    for (fragment_tag in fragmentTags){
        // Hide every Fragment that has been added and isn't the selected Fragment
        val fragment = supportFragmentManager.findFragmentByTag(fragment_tag)
        if (fragment != null && fragment != selectedFragment) {
            transaction.hide(fragment)
        }
    }
    transaction.show(selectedFragment!!)
    transaction.commit()
    return true
}

此方法无效。但是-如果我使用remove()add()而不是replace(),那么它可以正常工作:

OpeningFragment.kt

    val opening = fragmentManager?.findFragmentByTag("Opening")
    transaction?.remove(opening!!)
    transaction?.add(R.id.fragment_layout, playerDetailsFragment, "Add Player")
    transaction?.commit()
    gameString = "Add Player"

知道这是为什么吗?

1 个答案:

答案 0 :(得分:1)

对我来说,替换完全像文档所说的那样工作。它将删除给定容器ID中的所有片段,然后添加具有指定标签的新片段。

您的可选代码仅删除您想要的一个片段,而不是全部删除,因此替换功能并不相同。