Fragment回退栈
Fragment回退栈用于管理Fragment的导航历史(添加、删除、替换)。每个Activity都有一个包含其所有Fragment的FragmentManager,调用其addToBackStack方法时,这个事务就会被添加到FragmentManager的回退栈中当用户按下返回键时,系统就会从回退栈中弹出并反向执行最近的事务。如果你替换了一个Fragment,并将这个操作添加到了回退栈,那么按下返回键时,原来的Fragment会再次出现 commitNow()方法不能和addToBackStack()方法一起使用
XML文件
Activity 布局文件R.layout.activity_main
<?xml version="1.0" encoding="utf-8"?>
< LinearLayoutxmlns: 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"?>
< TextViewxmlns: 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"?>
< TextViewxmlns: 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代码
class MyFragmentA : Fragment ( ) { override fun onCreateView ( inflater: LayoutInflater, container: ViewGroup? , savedInstanceState: Bundle? ) : View? { return inflater. inflate ( R. layout. inflate_layout_a, container, false ) }
}
class MyFragmentB : Fragment ( ) { override fun onCreateView ( inflater: LayoutInflater, container: ViewGroup? , savedInstanceState: Bundle? ) : View? { return inflater. inflate ( R. layout. inflate_layout_b, container, false ) }
}
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 ? LinearLayoutmMainHandler. postDelayed ( { val firstFragment = MyFragmentA ( ) replaceLl? . let { replaceFragmentAddToStack ( firstFragment, it) } } , 1000 ) 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 ? LinearLayoutmMainHandler. postDelayed ( { val firstFragment = MyFragmentA ( ) replaceLl? . let { replaceFragmentAddToStack ( firstFragment, it) } } , 1000 ) mMainHandler. postDelayed ( { val secondFragment = MyFragmentB ( ) replaceLl? . let { replaceFragmentAddToStack ( secondFragment, it) } } , 2000 ) mMainHandler. postDelayed ( { supportFragmentManager. popBackStack ( ) } , 3000 ) 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 ? LinearLayoutmMainHandler. postDelayed ( { val firstFragment = MyFragmentA ( ) replaceLl? . let { addFragmentAddToStack ( firstFragment, it) } } , 1000 ) mMainHandler. postDelayed ( { val secondFragment = MyFragmentB ( ) replaceLl? . let { addFragmentAddToStack ( secondFragment, it) } } , 2000 ) mMainHandler. postDelayed ( { supportFragmentManager. popBackStack ( ) } , 3000 ) 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,此时屏幕上有MyFragmentA和MyFragmentB 3s移除橘色背景的MyFragmentB,此时屏幕上只有MyFragmentA 4s移除橘色背景的MyFragmentA,此时屏幕上没有任何Fragment