(1)Fragment生命周期
(2)Fragment学习总结
静态添加:
静态添加比较容易,自定义Fragment后。在res/layout的xml文件中以组件的形式如下写:
<fragment
android:name=”com.example.fragmenttest.FirstFrag”
…
...
/>
动态添加:
publicclass FirstFrag extends Fragment{
publicView onCreateView(LayoutInflater inflater,ViewGroup container,BundlesavedInstanceState){
Viewview=inflater.inflate(R.layout.first_frag,container,false);
returnview;
}
}
FirstFragmFrag=new FirstFrag();//调用默认的构造方法
FragmentManagerfm=getFragmentManager();
FragmentTransactionft=fm.beginTransaction();
//进行以下操作
ft.add(R.id.content,mFrag);//这里的R.id.content指的是一个容器。ViewGroup,可以是RelativeLayout,LinearLayout等。这个容器放在res/layout的某个xml文件中。
ft.replace
ft.remove
ft.hide
ft.show
ft.detach
ft.attatch
//
ft.addToBackStack();//添加到回退栈
那么每次按back键会回到上一个Fragment,当最后一个Fragment再按back键时,销毁Activity
ft.commit;//必不可少
等于整个过程中,要创建自定义Fragment的对象,FragmentManager的对象,FragmentTransaction对象。
(3)android.support.v4.app.ViewPager嵌套Fragment时,如何不用android.support.v4.app.Fragment,而是使用android.app.Fragment
当我们使用android.support.v4.app.FragmentPagerAdapter时候,必须使用v4包下的Fragment.
而当我们改用成android.support.v13.app.FragmentPagerAdapter时,就可以使用android.app.Fragment了。当然此时就不能使用v4包下的Fragment了。
(4)Fragment,View的切换
ViewmView=mFragment.getView();
(5)反复添加,切换,移除Fragment问题(出现白屏问题)
例如:多次使用调用同一行replace代码,相当于多次创造同一个Fragment对象,导致白屏。原因是之前的Fragment对象未能及时移除。
FragmentTransaction
transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.main_content,
fragment);
transaction.commit();
一般情况下,多个Fragment切换显示不同内容,会使Fragment实例化一个空的FrameLayout界面布局,并且初始化一个Fragment填充该布局。
问题描述:
Activity里的FrameLayout非空,有子布局ListView,在点击按钮后调用Fragment填充该FrameLayout,这样ListView就被替换掉,不显示。代码如下:
private FragmentManager frg_mng = getFragmentManager(); //全局变量
FragmentTransaction ft = frg_mng.beginTransaction();
switch(s) {
case a:
ft.replace(R.id.layout_note_list, mInfo_frg).commit();
break;
case b:
ft.replace(R.id.layout_note_list, mUsers_frg).commit();
break;
}
此时两个Fragment
mInfo_frg和mUsers_frg互相切换,那么如何显示Fragment所填充的FrameLayout下的ListView呢?显然要关闭两个Fragment,使用remove()方法可实现。
即:
FragmentTransaction ft = frg_mng.beginTransaction();
ft.remove(mUsers_frg).commit();
ft.remove(mInfo_frg).commit();
但是Fragment移除后,主Activity出错闪退。其原因是定义一次beginTransaction()方法只能commit()提交一次,要关闭两个Fragment,需要定义两个beginTransaction(),即:
FragmentTransaction ft_a = frg_mng.beginTransaction();
FragmentTransaction ft_b = frg_mng.beginTransaction();
ft_a.remove(mUsers_frg).commit();
ft_b.remove(mInfo_frg).commit();
这样,两个Fragment都顺利关闭,不再鸠占鹊巢,原FrameLayout下的ListView自然就能显示了,问题解决。
(3)解决IllegalStateException:Can not perform this action after onSaveInstanceState
大致意思是说我使用的 commit方法是在Activity的onSaveInstanceState()之后调用的,这样会出错,因为onSaveInstanceState
方法是在该Activity即将被销毁前调用,来保存Activity数据的,如果在保存玩状态后再给它添加Fragment就会出错。解决办法就
是把commit()方法替换成 commitAllowingStateLoss()就行了,其效果是一样的。
(7)Fragment的onActivityCreated()方法
onActivityCreated方法执行在onCreateView后面,在Activity的onCreate方法后执行。
onActivityCreated的应用场合:
①静态的view不需要onActivityCreated
②保存view的状态的时候需要用onActivityCreated
③访问父activity的view层的时候需要在onActivityCreated方法里面做
详细看第三条,一般来说Activity的view层组件是在onCreate的setContentView(R.layout.xxx)时实例化,注意不和findViewById区分(这个方法仅仅是获取到已经实例化的那个view对象,并不是实例化view对象)。
(8).getChildFragmentManager()
Fragment嵌套Fragment要用getChildFragmentManager
例如Fragment放ViewPager,ViewPager里面是fragment。如果想回去viewpager的page(fragment)的FragmentManager,就不能用getFragmentManager,而是要用getChildFragmentManager.
(9)FragmentManager的findFragmentByTag,返回fragment对象
FragmentTransation有方法add,replace等方法。
可以指定tag。//在事务中指明该fragment的tag
如果该fragment均没有id和tag,系统将使用containerview布局的id。
publicabstractFragmentTransaction add(intcontainerViewId, Fragment fragment, String tag);
publicabstractFragmentTransaction replace(intcontainerViewId, Fragment fragment, String tag);
一般tag可以是指定为Fragment的类名。
可以通过下面方式获得。
MfirstFragment.getClass().getName();
ViewPager中:
Fragment实例化的时候Android系统会给Fragment对象一个默认的tag
查看源代码android.support.v4.app.FragmentPagerAdapter
privateString getFragmentTag(int position){
//看源代码android.support.v4.app.FragmentPagerAdapter
return"android:switcher:"+R.id.pager+":"+position;
}
然后根据tag获取fragment对象
getActivity().getFragmentManager().findFragmentByTag(getFragmentTag(position));
这里的position是:如果有多个fragment,position是其顺序号,从0开始,0、1、2。。。
这里的R.id.pager是:fragment所在View容器控件id。
(10)一次性拿到回退栈的所有Fragment
List<Fragment>fragmentList = getSupportFragmentManager().getFragments();
(11)FragmentTransation的replace
replace=remove+add
所以前一个Fragment是被remove掉的,切记。
(12)Fragment,FragmentManager,FragmentTransation的常见相关方法。
Fragment:
getFragmentManager
getChildFragmentManager
onAttach
onCreate
onCreateView(返回值View)
onActivityCreated
onStart
onResume
onPause
onStop
onDestoryView
onDestory
onDetach
FragmentManager:
beginTransation(返回FragmentTransation)
findFragmentById
findFragmentByTag
FragmentTransation:
addToBackStack(Stringname);
commit
commitAllowingStateLoss
add
remove
replace
hide
show