簡體   English   中英

替換、添加、替換片段,然后導航返回按鈕不適用於第一個片段

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM