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()
}
}