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