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