Fragment详解

来源:互联网 发布:mac office 汉化 编辑:程序博客网 时间:2024/06/06 03:15

Fragment概述:

Fragmentactivity的界面中的一部分或一种行为。你可以把多个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工作。

    Android3.0开始引入fragment,主要是为了支持更动态更灵活的界面设计,比如在平板上的应用。平板机上拥有比手机更大的屏幕空间来组合和交互界面组件们。Fragment使你在做那样的设计时,不需应付view树中复杂的变化。通过把activitylayout分成fragment,你可以在activity运行时改变它的样子,并且可以在activity的后退栈中保存这些改变。

例如:写一个读新闻的程序,可以用一个fragment显示标题列表,另一个fragment显示选中标题的内容,这两个fragment都在一个activity上,并排显示。那么这两个fragment都有自己的生命周期并响应自己感兴趣的事件。于是,不需再像手机上那样用一个activity显示标题列表,用另一个activity显示新闻内容;现在可以把两者放在一个activity上同时显示出来。如下图:


Fragment的生命周期:

    要创建fragment,必须从FragmentFragment的派生类派生出一个类。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嵌入到activitylayout中。一个要为fragment提供layout,你必须实现onCreateView()回调方法,然后在这个方法中返回一个View对象,这个对象是fragmentlayout的根。

eg:    
public static class ExampleFragment extends Fragment{
    @Override
    public  View onCreateView(LayoutInflater inflaterViewGroup container,Bundle savedInstanceState){
        //Inflate the layout for this fragment
        return inflater.inflate(R.layout.example_fragment,container,false);          
    }
      
}
container是存放fragmentlayoutViewGroup对象

fragment添加到activity:

方法一:在activitylayoutxml文件中声明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,它有参数用于指定容纳fragmentViewGroup。如下:

ExampleFragment fragment =new ExampleFragment();
fragmentTransaction.add(R.id.fragment_container,fragment);
fragmentTransaction.commit();

    Add()的第一个参数是容器ViewGroup,第二个是要添加的fragment。一旦你通过FragmentTransactionfragment做出了改变,你必须调用方法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()