Fragment概述:
Fragment是activity的界面中的一部分或一种行为。你可以把多个Fragment们组合到一个activity中来创建一个多面界面并且你可以在多个activity中重用一个Fragment。你可以把Fragment认为模块化的一段activity,它具有自己的生命周期,接收它自己的事件,并可以在activity运行时被添加或删除。
Fragment不能独立存在,它必须嵌入到activity中,而且Fragment的生命周期直接受所在的activity的影响。例如:当activity暂停时,它拥有的所有的Fragment们都暂停了,当activity销毁时,它拥有的所有Fragment们都被销毁。然而,当activity运行时(在onResume()之后,onPause()之前),你可以单独地操作每个Fragment,比如添加或删除它们。当你在执行上述针对Fragment的事务时,你可以将事务添加到一个棧中,这个栈被activity管理,栈中的每一条都是一个Fragment的一次事务。有了这个栈,就可以反向执行Fragment的事务,这样就可以在Fragment级支持“返回”键(向后导航)。
当向activity中添加一个Fragment时,它须置于ViewGroup控件中,并且需定义Fragment自己的界面。你可以在layoutxml文件中声明Fragment,元素为:<fragment>;也可以在代码中创建Fragment,然后把它加入到ViewGroup控件中。然而,Fragment不一定非要放在activity的界面中,它可以隐藏在后台为actvitiy工作。
Android从3.0开始引入fragment,主要是为了支持更动态更灵活的界面设计,比如在平板上的应用。平板机上拥有比手机更大的屏幕空间来组合和交互界面组件们。Fragment使你在做那样的设计时,不需应付view树中复杂的变化。通过把activity的layout分成fragment,你可以在activity运行时改变它的样子,并且可以在activity的后退栈中保存这些改变。
例如:写一个读新闻的程序,可以用一个fragment显示标题列表,另一个fragment显示选中标题的内容,这两个fragment都在一个activity上,并排显示。那么这两个fragment都有自己的生命周期并响应自己感兴趣的事件。于是,不需再像手机上那样用一个activity显示标题列表,用另一个activity显示新闻内容;现在可以把两者放在一个activity上同时显示出来。如下图:
Fragment的生命周期:
要创建fragment,必须从Fragment或Fragment的派生类派生出一个类。Fragment的代码写起来有些像activity。它具有跟activity一样的回调方法,比如 onCreate(),onStart(),onPause()和onStop()。实际上,如果你想把老的程序改为使用fragment,基本上只需要把activity的回调方法的代码移到fragment中对应的方法即可。
下图为fragment的生命周期(它所在的activity处于运行状态)。
现成的fragment子类:
(1)DialogFragment
显示一个浮动的对话框。使用这个类创建对话框是替代activity创建对话框的最佳选择.因为你可以把fragmentdialog放入到activity的返回栈中,使用户能再返回到这个对话框。
(2)ListFragment
显示一个列表控件,就像ListActivity类,它提供了很多管理列表的方法,比如onListItemClick()方法响应click事件。
(3)PreferenceFragment
显示一个由Preference对象组成的列表,与PreferenceActivity相同。它用于为程序创建“设置”activity。
Fragment实现:
fragment一般作为activity的用户界面的一部分,把它自己的layout嵌入到activity的layout中。一个要为fragment提供layout,你必须实现onCreateView()回调方法,然后在这个方法中返回一个View对象,这个对象是fragment的layout的根。
eg:把fragment添加到activity:
方法一:在activity的layoutxml文件中声明fragment
<?xmlversion="1.0"encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:name="com.example.news.ArticleListFragment"
android:id="@+id/list"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent"/>
<fragment
android:name="com.example.news.ArticleReaderFragment"
android:id="@+id/viewer"
android:layout_weight="2"
android:layout_width="0dp"
android:layout_height="match_parent"/>
</LinearLayout>
方法二:在代码中添加fragment到一个ViewGroup
为了完成fragment的事务(比如添加,删除,替换等),你必须使用FragmentTransaction的方法。你可以从activity获取到FragmentTransaction,如下:
FragmentManager fragmentManager =getFragmentManager()
FragmentTransaction fragmentTransaction =fragmentManager.beginTransaction();
然后你可以用add()方法添加一个fragment,它有参数用于指定容纳fragment的ViewGroup。如下:
ExampleFragment fragment =new ExampleFragment();
fragmentTransaction.add(R.id.fragment_container,fragment);
fragmentTransaction.commit();
Add()的第一个参数是容器ViewGroup,第二个是要添加的fragment。一旦你通过FragmentTransaction对fragment做出了改变,你必须调用方法commit()提交这些改变。
Fragment管理:
要管理fragment们,需使用FragmentManager,要获取它,需在activity中调用方法getFragmentManager()。
你可以用FragmentManager来做以上事情:
1使用方法findFragmentById()或findFragmentByTag(),获取activity中已存在的fragment们。
2使用方法popBackStack()从activity的后退栈中弹出fragment们(这可以模拟后退键引发的动作)。
3用方法addOnBackStackChangedListerner()注册一个侦听器以监视后退栈的变化。
如果你向事务添加了多个动作,比如多次调用了add(),remove()等之后又调用了addToBackStack()方法,那么所有的在commit()之前调用的方法都被作为一个事务。当用户按返回键时,所有的动作都被反向执行(事务回溯)。
事务中动作的执行顺序可随意,但要注意以下两点:
1你必须最后调用commit()。
2如果你添加了多个fragment,那么它们的显示顺序跟添加顺序一至(后显示的覆盖前面的)。
如果你在执行的事务中有删除fragment的动作,而且没有调用addToBackStack(),那么当事务提交时,那些被删除的fragment就被销毁了。反之,那些fragment就不会被销毁,而是处于停止状态。当用户返回时,它们会被恢复。
对于fragment事务,你可以应用动画。在commit()之前调用setTransition()就行。
只能在 activity 处于可保存状态的状态时,比如 running 中, onPause() 方法和 onStop() 方法中提交事务,否则会引发异常。这是因为 fragment 的状态会丢失。如果要在可能丢失状态的情况下提交事务,请使用 commitAllowingStateLoss() 。