FragmentManager 之 addToBackStack 作用

FragmentManager 管理 Fragment 返回堆栈。在运行时,FragmentManager 可以执行添加或移除 Fragment 等返回堆栈操作来响应用户互动。每一组更改作为一个单元(称为 FragmentTransaction)一起提交。

当用户点按设备上的返回按钮时,或者你调用 FragmentManager.popBackStack() 时,最上面的 Fragment 事务会从堆栈中弹出。如果堆栈上没有更多 Fragment 事务,并且你没有使用子 Fragment,则返回事件会向上传递到 Activity。

弹出返回堆栈时,所有这些操作会作为一项原子化操作反转。不过,如果你在调用 popBackStack() 之前提交了其他事物,并且你没有对事务使用 addToBackStack(), 则这些操作不会反转。

案例1

如果没有对事务使用 addToBackStack(), 在 MainActivity 中点击设备的返回按钮,整个应用退出。

kotlin 复制代码
class MainActivity : AppCompatActivity() {
    companion object {
        private const val TAG = "MainActivity"
    }

    private lateinit var mBinding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)

        loadFragment(MainFragment(), "mainFragment", false)
    }

    private fun loadFragment(fragment: Fragment, tag: String, addToBackStack: Boolean) {
        val transaction = supportFragmentManager.beginTransaction()
            .replace(R.id.fragment_container, fragment, tag)
        if (addToBackStack) {
            transaction.addToBackStack(tag)
        }
        transaction.commit()
    }
}

案例2

如果对事务使用 addToBackStack(), 在 MainActivity 中点击设备的返回按钮,MainFragment 会退出,MainActivity 会在返回堆栈栈顶。

kotlin 复制代码
class MainActivity : AppCompatActivity() {
    companion object {
        private const val TAG = "MainActivity"
    }

    private lateinit var mBinding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)

        loadFragment(MainFragment(), "mainFragment", true)
    }

    private fun loadFragment(fragment: Fragment, tag: String, addToBackStack: Boolean) {
        val transaction = supportFragmentManager.beginTransaction()
            .replace(R.id.fragment_container, fragment, tag)
        if (addToBackStack) {
            transaction.addToBackStack(tag)
        }
        transaction.commit()
    }
}

案例3

在 btnMain, btnFirst 和 btnMain 三个点击事件中的 FragmentTransaction 都使用 addToBackStack, 点击生成的 FragmentTransaction 都会存入返回堆栈中,点击设备的返回键,则会按顺序逐一复原

kotlin 复制代码
class MainActivity : AppCompatActivity() {
    companion object {
        private const val TAG = "MainActivity"
    }

    private lateinit var mBinding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)

        loadFragment(MainFragment(), "mainFragment", false)

        mBinding.btnMain.setOnClickListener(object: View.OnClickListener {
            override fun onClick(p0: View?) {
                Log.i(TAG, "BtnMain click")
                loadFragment(MainFragment(), "mainFragment", true)
            }
        })

        mBinding.btnFirst.setOnClickListener(object: View.OnClickListener {
            override fun onClick(p0: View?) {
                Log.i(TAG, "BtnFirst click")
                loadFragment(FirstFragment(), "firstFragment", true)
            }
        })

        mBinding.btnSecond.setOnClickListener(object: View.OnClickListener {
            override fun onClick(p0: View?) {
                Log.i(TAG, "BtnSecond click")
                loadFragment(SecondFragment(), "secondFragment", true)
            }
        })
    }

    private fun loadFragment(fragment: Fragment, tag: String, addToBackStack: Boolean) {
        val transaction = supportFragmentManager.beginTransaction()
            .replace(R.id.fragment_container, fragment, tag)
        if (addToBackStack) {
            transaction.addToBackStack(tag)
        }
        transaction.commit()
    }
}
相关推荐
xiaotao1312 小时前
第九章:Vite API 参考手册
前端·vite·前端打包
午安~婉2 小时前
Electron桌面应用聊天(续)
前端·javascript·electron
哈里谢顿3 小时前
如何实现分布式锁
面试
彧翎Pro3 小时前
基于 RO1 noetic 配置 robosense Helios 32(速腾) & xsense mti 300
前端·jvm
小码哥_常3 小时前
解锁系统设置新姿势:Activity嵌入全解析
前端
之歆3 小时前
前端存储方案对比:Cookie-Session-LocalStorage-IndexedDB
前端
哟哟耶耶3 小时前
vue3-单文件组件css功能(:deep,:slotted,:global,useCssModule,v-bind)
前端·javascript·css
是罐装可乐3 小时前
深入理解“句柄(Handle)“:从浏览器安全到文件系统访问
前端·javascript·安全
华科易迅4 小时前
Vue如何集成封装Axios
前端·javascript·vue.js
康一夏4 小时前
Next.js 13变化有多大?
前端·react·nextjs