[英]Replace, add, replace fragment, then the Navigation Back button not working for first fragment
我有一個片段堆棧,我在其中使用替換和相加。 添加或替換我的片段的代碼(在我的活動中)如下
private fun addFragment(fragment: Fragment, name: String) {
supportFragmentManager.beginTransaction().add(R.id.container, fragment)
.addToBackStack(name).commit()
}
private fun replaceFragment(fragment: Fragment, name: String) {
supportFragmentManager.beginTransaction().replace(R.id.container, fragment)
.addToBackStack(name).commit()
}
在我的片段中,我確實有一個帶有主菜單后退圖標的工具欄。 單擊后,它應該有助於將我的片段彈出到上一個堆棧。
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
toolbar_actionbar.setNavigationIcon(R.drawable.ic_arrow_back_black_24dp)
setHasOptionsMenu(true)
(activity as AppCompatActivity).setSupportActionBar(toolbar_actionbar)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return if (item.itemId == android.R.id.home) {
activity?.onBackPressed()
true
} else {
super.onOptionsItemSelected(item)
}
}
為了清楚起見,我顯示活動 onBackPressed 編碼如下
override fun onBackPressed() {
if (supportFragmentManager.backStackEntryCount > 0) {
supportFragmentManager.popBackStackImmediate()
} else {
super.onBackPressed()
}
}
現在,如果我添加fragment1,添加fragment2,添加fragment3,添加fragment4,然后按后退、后退、后退、后退……一切正常。
同樣,如果我用 fragment1 替換,用 fragment2 替換,用 fragment3 替換,用 fragment4 替換,然后返回,返回,返回,返回,一切正常。
但是,如果我這樣做,請用片段 1 替換,添加片段 2,然后用片段 3 替換,然后按后退、后退、后退.... 第三次按后退不再起作用。 為什么??
為了更好地說明這一點,我將我的代碼放在 github 中,如下所示https://github.com/elye/issue_android_fragment_replace_add_replace
並記錄成下面的gif(63秒gif)顯示,4個添加作品,4個替換作品,但是替換和添加混合使用,會導致工具欄返回按鈕在幾次返回后不起作用。
請注意,添加片段顯示重疊數,因為背景是透明的。 這樣做是為了輕松區分添加與替換。
我懷疑這是一個谷歌錯誤,但思想應該分享,以防我錯過任何重要的事情。
經過調查,問題似乎如下所述。
由於每個片段都有自己的操作欄設置(在此 stackoverflow 中,我將其簡化為僅單擊 R.id.home 以便更容易地說明問題)。 添加/刪除片段時,每個人都會調用以下代碼。
(activity as AppCompatActivity).setSupportActionBar(toolbar_actionbar)
當我們執行添加-添加-替換(或替換-添加-替換)時......我們在后台堆棧中有 3 個片段,但只有一個可見。 因為最后一次替換,將刪除較早的 2 個片段。
當我們點擊后退按鈕時,會彈出最后一個替換的片段,然后系統恢復前2個片段。
在恢復前 2 個片段期間,以下代碼會在短時間內為兩個片段調用
(activity as AppCompatActivity).setSupportActionBar(toolbar_actionbar)
我懷疑這會導致第一個片段的工具欄未完全設置的某些行為(Android SDK 錯誤?)。
為了解決這個問題,當我們再次彈出第 2 個片段時,我們必須強制第一個片段調用
(activity as AppCompatActivity).setSupportActionBar(toolbar_actionbar)
對於上述問題,我的解決方法是在 onResume() 中使用上面的代碼。
override fun onResume() {
super.onResume()
(activity as AppCompatActivity).setSupportActionBar(toolbar_actionbar)
}
每當片段 backstack 發生變化時,我都會調用頂部片段的 onResume
supportFragmentManager.addOnBackStackChangedListener {
val currentFragment = supportFragmentManager.findFragmentById(R.id.container)
currentFragment?.onResume()
}
這現在有助於確保無論替換-添加堆棧混合如何,工具欄菜單都將繼續工作。
我在https://github.com/elye/issue_android_fragment_replace_add_replace_workaround 中有示例解決方法代碼
這實際上是一種解決方法而不是解決方案。 我希望發布一些更好的答案,或者如果這確實是一個 Google Bug,可以在以后的 SDK 版本中修復它。
試試這個
if (supportFragmentManager.backStackEntryCount > 1) {
supportFragmentManager.popBackStackImmediate()
} else {
super.onBackPressed()
}
嗨,將您的工具欄代碼和它的 xml 部分放入 MainActivity 中,它是相關的布局,並從所有文件和布局中刪除。 並放置如下代碼:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
toolbar_actionbar.setNavigationIcon(R.drawable.ic_arrow_back_black_24dp)
setSupportActionBar(toolbar_actionbar)
}
並將下面的代碼寫入 MainActivity 來解決它。
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return if (item.itemId == android.R.id.home) {
if (supportFragmentManager.backStackEntryCount > 0) {
supportFragmentManager.popBackStackImmediate()
} else {
super.onBackPressed()
}
true
} else {
super.onOptionsItemSelected(item)
}
}
我已經測試過並且工作得很好。 希望對你有幫助。 如果您有任何疑問,請在下方評論/留言,我會向您解釋並解決您的問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.