Android开发之fragment的生命周期与使用

来源:互联网 发布:echarts map.js使用 编辑:程序博客网 时间:2024/06/05 15:52

概述:fragment是一种控制器对象,activity可委派它完成一些任务。并且,activity中可以插入多个fragment。下边先贴两张图,供记忆。

activity生命周期:


fragment生命周期:


对比:


场景演示 : 切换到该Fragment

11-29 14:26:35.095: D/AppListFragment(7649): onAttach
11-29 14:26:35.095: D/AppListFragment(7649): onCreate
11-29 14:26:35.095: D/AppListFragment(7649): onCreateView
11-29 14:26:35.100: D/AppListFragment(7649): onActivityCreated
11-29 14:26:35.120: D/AppListFragment(7649): onStart
11-29 14:26:35.120: D/AppListFragment(7649): onResume

屏幕灭掉:

11-29 14:27:35.185: D/AppListFragment(7649): onPause
11-29 14:27:35.205: D/AppListFragment(7649): onSaveInstanceState
11-29 14:27:35.205: D/AppListFragment(7649): onStop


屏幕解锁

11-29 14:33:13.240: D/AppListFragment(7649): onStart
11-29 14:33:13.275: D/AppListFragment(7649): onResume


切换到其他Fragment:
11-29 14:33:33.655: D/AppListFragment(7649): onPause
11-29 14:33:33.655: D/AppListFragment(7649): onStop
11-29 14:33:33.660: D/AppListFragment(7649): onDestroyView


切换回本身的Fragment:

11-29 14:33:55.820: D/AppListFragment(7649): onCreateView
11-29 14:33:55.825: D/AppListFragment(7649): onActivityCreated
11-29 14:33:55.825: D/AppListFragment(7649): onStart
11-29 14:33:55.825: D/AppListFragment(7649): onResume

回到桌面

11-29 14:34:26.590: D/AppListFragment(7649): onPause
11-29 14:34:26.880: D/AppListFragment(7649): onSaveInstanceState
11-29 14:34:26.880: D/AppListFragment(7649): onStop

回到应用

11-29 14:36:51.940: D/AppListFragment(7649): onStart
11-29 14:36:51.940: D/AppListFragment(7649): onResume


退出应用

11-29 14:37:03.020: D/AppListFragment(7649): onPause
11-29 14:37:03.155: D/AppListFragment(7649): onStop
11-29 14:37:03.155: D/AppListFragment(7649): onDestroyView
11-29 14:37:03.165: D/AppListFragment(7649): onDestroy
11-29 14:37:03.165: D/AppListFragment(7649): onDetach


比Activity多了一些生命周期,完整和Activity对接上,大家好好利用。

以上参考自:http://blog.csdn.net/forever_crying/article/details/8238863/


1. fragment的简单用法

Activity中有个FragmentManager,其内部维护fragment队列,以及fragment事务的回退栈。

public class UserActivityextends FragmentActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_user);FragmentManager fm = getSupportFragmentManager();Fragment fragment = fm.findFragmentById(R.id.fragmentcontainer);if (fragment ==null) {fragment = new UserFragment();fm.beginTransaction().add(R.id.fragmentcontainer, fragment).commit();}}}


      最迷糊的地方在于以上代码中的红色部分。FragmentManager使用容器的id去识别其中的fragment,这看上去有点怪。但实际上,FragmentManager的内部机制就是这么实现的。首先,使用fm.findFragmentById(R.id.fragmentcontainer)请求获取fragment。如要获取的fragment在队列中已经存在,FragmentManager随机会将之返还。为什么队列中已经有fragment存在了呢?activity会因设备旋转或内存回收被销毁后重建,Activity.onCreate()方法会响应activity的重建而被调用。activity被销毁时,它的FragmentManager会将fragment队列保存下来。这样,activity重建时,新的FragmentManager会首先获取保存的队列,然后重建fragment队列,从而恢复到原来的状态。另一方面,如获取fragment不存在,则fragment==null。这时应创建新的fragment,开启一个新的fragment事物,然后将新的fragment添加到队列中。


2. fragment获取数据(数据可能从activity或fragment通过intent传递而来)

     2.1直接获取extra信息的方式

     使用getActivity().getIntent().getExtra(...);方法就能获取传递而来的数据。其弊端在于:牺牲了fragment的封装性,fragment不再是可以复用的单元,总是需要某个activity来托管着。一个比较好的做法是:将要传递的参数存储在fragment(arguments)的某个地方,而不是将它保存在依托于activity的私有空间中。无需依赖activity的intent的存在,就能获取fragment所需的数据。

    2.2使用fragment argument方式

     附加argument bundle给fragment,需要调用Fragment.setArguments(Bundle)方法。注意,该任务必须在fragment创建后,添加给activity前完成。习惯做法是:在Fragment类中添加newInstance()的静态方法,使用该方法,完成fragment实例及bundle对象的创建,然后将argument放入bundle中,最后再附加给fragment。托管activity需要fragment实例时,需调用newInstance()方法,而非直接调用其构造方法。而且,为满足fragment创建argument的需求,activity可传入任何需要的参数给newInstance()方法。

<span style="font-size:14px;">public class ContentFragment extends Fragment  {        private String mArgument;      public static final String FRAGMENT_ARGUMENTS = "argument";        @Override      public void onCreate(Bundle savedInstanceState)      {          super.onCreate(savedInstanceState);          Bundle bundle = getArguments();//获取参数          if (bundle != null)              mArgument = bundle.getString(ARGUMENT);        }        /**      * 传入需要的参数,设置给arguments      * @param argument      * @return      */      public static ContentFragment newInstance(String argument)      {          Bundle bundle = new Bundle();          bundle.putString(</span><span style="font-size:12px;">FRAGMENT_ARGUMENTS</span><span style="font-size:14px; font-family: Arial, Helvetica, sans-serif;"> </span><span style="font-size:14px;">, argument);          ContentFragment contentFragment = new ContentFragment();          contentFragment.setArguments(bundle);          return contentFragment;      }</span><pre name="code" class="java" style="font-size:14px;">}</span>

在activity中实例化fragment时,调用newInstance(...)方法。使用getArguments()来获取存储在fragment中的参数。

3. fragment不具有setResult(...)方法(通过fragment获取返回结果)

    fragment拥有startActivityForResult(...)和onActivityResult(...)方法,但不具有setResult(...)方法。因为只有activity拥有返回结果。

4. 保证fragment的独立性,同一个activity中多个fragment之间的数据传递。

       为了重用Fragment UI组件,你应该把每一个fragment都构建成完全的自包含的、模块化的组件,定义他们自己的布局与行为。当你定义好这些模块化的Fragment,你就可以让他们关联activity,使他们与application的逻辑结合起来,实现全局的复合的UI。也就是说,保证fragment的独立性模块化,在fragment中的任何操作,都是通过activity来具体实现。

具体实现:

a.    定义一个接口(在fragment中)

为了让fragment与activity交互,你可以在Fragment 类中定义一个接口,并且在activity中实现这个接口。Fragment在他们生命周期的onAttach()方法(系统在向 Activity 添加片段时调用的方法)中获取接口的实现,然后调用接口的方法来与Activity交互。


现在Fragment就可以通过调用 OnHeadlineSelectedListener 接口实例的 mCallback 中的 onArticleSelected() (也可以是其它方法)方法与activity传递消息。也就是说,fragment的消息传递给activity,由activity来实现。

举个例子,在fragment中的下面的方法在用户点击列表条目时被调用,fragment 用回调接口来传递事件给父Activity.



b.    实现接口(在activity中)

了接收回调事件,宿主activity必须实现在Fragment中定义的接口。举个例子,下面的activity实现了上面例子中的接口。


c.    传消息给Fragment

宿主activity通过findFragmentById()方法来获取fragment的实例,然后直接调用Fragment的public方法来向fragment传递消息。例如,假设上面所示的activity可能包含另外一个fragment,这个fragment用来展示从上面的回调方法中返回的指定的数据。在这种情况下,activity可以把从回调方法中接收到的信息传递给这个展示数据的Fragment.也就是说,activity收到第一个fragment的消息,要将消息展示或者说传递给第二个fragment。


参考:https://developer.android.com/guide/components/fragments.html



1 0
原创粉丝点击