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"?>
< 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
代码
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 ? LinearLayout
mMainHandler. 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 ? LinearLayout
mMainHandler. 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 ? LinearLayout
mMainHandler. 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