Fragment回退栈

  • Fragment回退栈用于管理Fragment的导航历史(添加、删除、替换)。每个Activity都有一个包含其所有FragmentFragmentManager,调用其addToBackStack方法时,这个事务就会被添加到FragmentManager的回退栈中
  • 当用户按下返回键时,系统就会从回退栈中弹出并反向执行最近的事务。如果你替换了一个Fragment,并将这个操作添加到了回退栈,那么按下返回键时,原来的Fragment会再次出现
  • commitNow()方法不能和addToBackStack()方法一起使用

XML文件

  • Activity 布局文件R.layout.activity_main
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/replace_child_ll"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/holo_green_light"
    android:gravity="center"
    android:orientation="vertical">
</LinearLayout>
  • 第一次添加的MyFragmentA布局R.layout.inflate_layout_a
<?xml version="1.0" encoding="utf-8"?>
<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/inflate_tv_a"
    android:layout_width="match_parent"
    android:layout_height="100dp"
    android:background="@android:color/holo_blue_light" />
  • 第二次添加的MyFragmentB布局R.layout.inflate_layout_b
<?xml version="1.0" encoding="utf-8"?>
<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/inflate_tv_b"
    android:layout_width="match_parent"
    android:layout_height="100dp"
    android:background="@android:color/holo_orange_light"/>

Activity代码和Fragment代码

  • MyFragmentA代码
class MyFragmentA : Fragment() {
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.inflate_layout_a, container, false)
    }
}
  • MyFragmentB代码
class MyFragmentB : Fragment() {
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.inflate_layout_b, container, false)
    }
}
  • Activity代码
const val TAG = "Yang"
class MainActivity : AppCompatActivity() {
    var replaceLl : LinearLayout? = null
    var mMainHandler = Handler(Looper.getMainLooper())
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        replaceLl = findViewById(R.id.replace_child_ll) as? LinearLayout
        // 添加第一个Fragment
        mMainHandler.postDelayed({
            val firstFragment = MyFragmentA()
            replaceLl?.let {
                replaceFragmentAddToStack(firstFragment, it)
            }
        }, 1000)
        // 添加第二个Fragment
        mMainHandler.postDelayed({
            val secondFragment = MyFragmentB()
            replaceLl?.let {
                replaceFragmentAddToStack(secondFragment, it)
            }
        }, 2000)
    }


    private fun replaceFragmentAddToStack(fragment: Fragment, targetView: View) {
        val transaction = supportFragmentManager.beginTransaction()
        transaction?.replace(targetView.id, fragment)
            ?.addToBackStack(null)
            ?.commitAllowingStateLoss()
    }
}

效果图

  • 3s后添加蓝色背景的MyFragmentA,6s后添加橘色背景的MyFragmentB
  • 按下第一次返回键后,最上层的橘色背景的MyFragmentB销毁,下层蓝色背景的MyFragmentA显示
  • 按下第二次返回键后,最上层的蓝色背景的MyFragmentA销毁,下层绿色背景的Activity显示
  • 按下第三次返回键后,最上层的绿色背景的Activity执行onPause()onStop(),应用进入后台
    在这里插入图片描述

FragmentManger.popBackStack()

  • 如果在Activity添加Fragment时,通过addToBackStack添加到回退栈,popBackStack的作用和按下返回键一样

replace方式添加+addToBackStack+popBackStack

class MainActivity : AppCompatActivity() {
    var replaceLl : LinearLayout? = null
    var mMainHandler = Handler(Looper.getMainLooper())
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        replaceLl = findViewById(R.id.replace_child_ll) as? LinearLayout
        // 添加第一个Fragment
        mMainHandler.postDelayed({
            val firstFragment = MyFragmentA()
            replaceLl?.let {
                replaceFragmentAddToStack(firstFragment, it)
            }
        }, 1000)

        // 添加第二个Fragment
        mMainHandler.postDelayed({
            val secondFragment = MyFragmentB()
            replaceLl?.let {
                replaceFragmentAddToStack(secondFragment, it)
            }
        }, 2000)

        // 移除第二个Fragment
        mMainHandler.postDelayed({
            supportFragmentManager.popBackStack()
        }, 3000)

        // 移除第一个Fragment
        mMainHandler.postDelayed({
            supportFragmentManager.popBackStack()
        }, 4000)
    }

    private fun replaceFragmentAddToStack(fragment: Fragment, targetView: View) {
        val transaction = supportFragmentManager.beginTransaction()
        transaction?.replace(targetView.id, fragment)
            ?.addToBackStack(null)
            ?.commit()
    }
}

效果图

  • 1s添加蓝色背景的MyFragmentA
  • 2s添加橘色背景的MyFragmentB,移除蓝色背景的MyFragmentA,此时屏幕上只有MyFragmentB
  • 3s移除橘色背景的MyFragmentB,显示蓝色背景的MyFragmentA,此时屏幕上只有MyFragmentA
  • 4s移除橘色背景的MyFragmentA,移除蓝色背景的MyFragmentA,此时屏幕上没有任何Fragment
    在这里插入图片描述

add方式添加+addToBackStack+popBackStack

class MainActivity : AppCompatActivity() {
    var replaceLl : LinearLayout? = null
    var mMainHandler = Handler(Looper.getMainLooper())
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        replaceLl = findViewById(R.id.replace_child_ll) as? LinearLayout
        // 添加第一个Fragment
        mMainHandler.postDelayed({
            val firstFragment = MyFragmentA()
            replaceLl?.let {
                addFragmentAddToStack(firstFragment, it)
            }
        }, 1000)

        // 添加第二个Fragment
        mMainHandler.postDelayed({
            val secondFragment = MyFragmentB()
            replaceLl?.let {
                addFragmentAddToStack(secondFragment, it)
            }
        }, 2000)

        // 移除第二个Fragment
        mMainHandler.postDelayed({
            supportFragmentManager.popBackStack()
        }, 3000)

        // 移除第一个Fragment
        mMainHandler.postDelayed({
            supportFragmentManager.popBackStack()
        }, 4000)
    }

    private fun addFragmentAddToStack(fragment: Fragment, targetView: View) {
        val transaction = supportFragmentManager.beginTransaction()
        transaction?.add(targetView.id, fragment)
            ?.addToBackStack(null)
            ?.commit()
    }
}

效果图

  • 1s添加蓝色背景的MyFragmentA
  • 2s添加橘色背景的MyFragmentB,不移除蓝色背景的MyFragmentA,此时屏幕上有MyFragmentAMyFragmentB
  • 3s移除橘色背景的MyFragmentB,此时屏幕上只有MyFragmentA
  • 4s移除橘色背景的MyFragmentA,此时屏幕上没有任何Fragment
    在这里插入图片描述

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部