然后在onCreate()中,通过以下代码将Fragment添加进Activity中。
if (bundle == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, Fragment1.newInstance(“hello world”),“f1”)
//.addToBackStack(“fname”)
.commit();
}
这里需要注意几点:
因为我们使用了support库的Fragment,因此需要使用
getSupportFragmentManager()
获取FragmentManager,通过getSupportFragmentManager()
获取的FragmentManager只能管理Activity里面嵌入的所有一级fragment
。add()是对Fragment众多操作中的一种,还有
remove()
,replace()
等,第一个参数是根容器的id(FrameLayout的id,即”@id/container”),第二个参数是Fragment对象,第三个参数是fragment的tag名,指定tag的好处是后续我们可以通过Fragment1 frag = getSupportFragmentManager().findFragmentByTag("f1")
从FragmentManager中查找Fragment对象。在一次事务中,可以做多个操作,比如同时做
add()
.remove()
.replace()
。
commit()
操作是异步的,内部通过mManager.enqueueAction()
加入处理队列。对应的同步方法为commitNow()
,commit()
内部会有checkStateLoss()
操作,如果开发人员使用不当(比如commit()操作在onSaveInstanceState()之后),可能会抛出异常,而commitAllowingStateLoss()
方法则是不会抛出异常版本的commit()
方法,但是尽量使用commit(),而不要使用commitAllowingStateLoss()
。addToBackStack(“fname”)是可选的。FragmentManager拥有回退栈(BackStack),类似于Activity的任务栈,如果添加了该语句,就把该事务加入回退栈,当用户点击返回按钮,会回退该事务(回退指的是如果事务是add(frag1),那么回退操作就是remove(frag1));如果没添加该语句,用户点击返回按钮会直接销毁Activity。
Fragment有一个常见的问题,即Fragment重叠问题,这是由于Fragment被系统杀掉,并重新初始化时再次将fragment加入activity,因此通过在外围加if语句能判断此时是否是被系统杀掉并重新初始化的情况。解决方法有三种
- 第一种方式,在 Activity 提供的 onAttachFragment() 方法中处理:
@Override public void onAttachFragment(Fragment fragment) { super.onAttachFragment(fragment); if (fragment instanceof OneFragment){ oneFragment = (OneFragment) fragment; } }
* 第二种方式,在创建 Fragment 前添加判断,判断是否已经存在:
Fragment tempFragment = getSupportFragmentManager() .findFragmentByTag("OneFragment"); if (tempFragment==null) { oneFragment = OneFragment.newInstance(); ft.add(R.id.fl_content, oneFragment, "OneFragment"); }else { oneFragment = (OneFragment) tempFragment; }
* 第三种方式,更为简单,直接利用 savedInstanceState 判断即可:
if (savedInstanceState==null) { oneFragment = OneFragment.newInstance(); ft.add(R.id.fl_content, oneFragment, "OneFragment"); }else { oneFragment = (OneFragment) getSupportFragmentManager().findFragmentByTag("OneFragment"); }
Fragment有个常见的异常:
java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1341) at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1352) at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:595) at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:574)
该异常出现的原因是:commit()在onSaveInstanceState()后调用。首先,onSaveInstanceState()是在Activity
有可能被
系统回收的情况下,而且是在onPause()之后,onStop()之前调用。onRestoreInstanceState()在onStart()之后,onResume()之前。
解释一下:
onSaveInstanceState()
是当activity
有可能被
系统回收的情况下,而且是在onStop()之前。注意是有可能