Fragment相关知识点学习

来源:互联网 发布:windows7安装mac os x 编辑:程序博客网 时间:2024/06/07 11:56

(1)Fragment生命周期


(2)Fragment学习总结

静态添加:

静态添加比较容易,自定义Fragment后。在res/layoutxml文件中以组件的形式如下写:

<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对象未能及时移除。
FragmentTransactiontransaction = 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; 

此时两个FragmentmInfo_frgmUsers_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方法是在ActivityonSaveInstanceState()之后调用的,这样会出错,因为onSaveInstanceState
方法是在该Activity即将被销毁前调用,来保存Activity数据的,如果在保存玩状态后再给它添加Fragment就会出错。解决办法就
是把commit()方法替换成commitAllowingStateLoss()就行了,其效果是一样的。

(7)FragmentonActivityCreated()方法

onActivityCreated方法执行在onCreateView后面,在ActivityonCreate方法后执行。

onActivityCreated的应用场合:

静态的view不需要onActivityCreated

保存view的状态的时候需要用onActivityCreated

访问父activityview层的时候需要在onActivityCreated方法里面做

详细看第三条,一般来说Activityview层组件是在onCreatesetContentView(R.layout.xxx)时实例化,注意不和findViewById区分(这个方法仅仅是获取到已经实例化的那个view对象,并不是实例化view对象)。

(8).getChildFragmentManager()

Fragment嵌套Fragment要用getChildFragmentManager

例如FragmentViewPagerViewPager里面是fragment。如果想回去viewpagerpage(fragment)FragmentManager,就不能用getFragmentManager,而是要用getChildFragmentManager.

(9)FragmentManagerfindFragmentByTag,返回fragment对象

FragmentTransation有方法add,replace等方法。

可以指定tag//在事务中指明该fragmenttag

如果该fragment均没有idtag,系统将使用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是:如果有多个fragmentposition是其顺序号,从0开始,012。。。

这里的R.id.pager是:fragment所在View容器控件id

(10)一次性拿到回退栈的所有Fragment

List<Fragment>fragmentList = getSupportFragmentManager().getFragments();

(11)FragmentTransationreplace

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