activity与fragment 的生命周期的使用

Fragment与Activity简单使用,包括二者之间的关联与生命周期
随着Android系统的多样化,不仅仅在手机上,在平板、电视等设备上应用的也越来越多,这样就会有一个需要适应不同屏幕的问题。在Android3.0之后,谷歌推出了Fragment,Fragment在Android中被称为碎片。 我们可以把Fragment看作是Activity的一个界面或者组成部分,而且Fragment具有与Activity很相似的生命周期,我们可以在Activity中动态的添加或者移除某个Fragment。

官网帮助文档链接:
 http://developer.android.com/guide/components/fragments.html

1、onAttach(Activity activity)


作用:fragment已经关联到activity,

    这个是 回调函数
    @Override
    public void onAttach(Activity activity) {
            super.onAttach(activity);
            Log.i("onAttach_Fragment");
    }
    这个时候 activity已经传进来了
    获得activity的传递的值
    就可以进行 与activity的通信里
    当然也可以使用getActivity(),前提是这个fragment已经和宿主的activity关联,并且没有脱离
    他只调用一次。


2、onCreate() 


系统创建fragment的时候回调他,在他里面实例化一些变量 
这些个变量主要是:当你 暂停 停止的时候 你想保持的数据 
如果我们要为fragment启动一个后台线程,可以考虑将代码放于此处。 
参数是:Bundle savedInstance, 用于保存 Fragment 参数, Fragement 也可以 重写 onSaveInstanceState(BundleoutState) 方法, 保存Fragement状态; 
可以用于 文件保护 
他只调用一次。

3、onCreateView()

    第一次使用的时候 fragment会在这上面画一个layout出来,
    为了可以画控件 要返回一个 布局的view,也可以返回null
 
    当系统用到fragment的时候 fragment就要返回他的view,越快越好,所以尽量在这里不要做耗时操作,比如从数据库加载大量数据显示listview,当然线程还是可以的。
 
    给当前的fragment绘制ui布局,可以使用线程更新UI
    说白了就是加载fragment的布局的。
    这里一般都先判断是否为null
if(text==null){
            Bundle args=getArguments();
            text=args.getString("text");
        }
        if (view == null) {
            view = inflater.inflate(R.layout.hello, null);
        }
这样进行各判断省得每次都要加载,减少资源消耗

4、onActivityCreated()

    当Activity中的onCreate方法执行完后调用。    
 
    注意了:
    从这句官方的话可以看出:当执行onActivityCreated()的时候 activity的onCreate才刚完成。所以在onActivityCreated()调用之前 activity的onCreate可能还没有完成,所以不能再onCreateView()中进行 与activity有交互的UI操作,UI交互操作可以砸onActivityCreated()里面进行。
    所以呢:这个方法主要是初始化那些你需要你的父Activity或者Fragment的UI已经被完整初始化才能初始化的元素。
    如果在onCreateView里面初始化空间 会慢很多,比如listview等


5、onStart()

    和activity一致 启动, Fragement 启动时回调, 此时Fragement可见;


6、onResume()

    和activity一致  在activity中运行是可见的
    激活, Fragement 进入前台, 可获取焦点时激活;


7、onPause()

    和activity一致  其他的activity获得焦点,这个仍然可见
    第一次调用的时候,指的是 用户 离开这个fragment(并不是被销毁)
    通常用于 用户的提交(可能用户离开后不会回来了)


8、onStop()

    和activity一致
    fragment不可见的, 可能情况:activity被stopped了 OR  fragment被移除但被加入到回退栈中
    一个stopped的fragment仍然是活着的如果长时间不用也会被移除


9、onDestroyView()

    Fragment中的布局被移除时调用。
    表示fragemnt销毁相关联的UI布局
    清除所有跟视图相关的资源
 
    以前以为这里没什么用处其实 大有文章可做,
    相信大家都用过ViewPager+Fragment,由于ViewPager的缓存机制,每次都会加载3页。
    例如:有四个 fragment 当滑动到第四页的时候 第一页执行onDestroyView(),但没有执行onDestroy。他依然和activity关联。当在滑动到第一页的时候又执行了 onCreateView()。 生命周期可以自己试一下。
    那么问题来了。会出现重复加载view的局面,所以这么做(下面是先人的代码)
@Override
    public void onDestroyView() {
        Log.i("onDestroyView_Fragment");
        if(view!=null){
                        ((ViewGroup)view.getParent()).removeView(view);
        }
        super.onDestroyView();
    }


10、onDestroy()

    销毁fragment对象
    跟activity类似了。


11、onDetach()

    Fragment和Activity解除关联的时候调用。
    脱离activity
可见fragment的销毁还是很优雅地,一个一个的来。


Fragment的生命周期

  你可以把fragment看作是activity的模块化组件,它拥有自己的生命周期

  

  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级支持“返回”键(向后导航)。

  一、显示Fragment时(跟用户交互)要调用的核心的生命周期方法如下:

  1. 把Fragment对象跟Activity关联时,调用onAttach(Activity)方法;

  2. Fragment对象的初始创建时,调用onCreate(Bundle)方法;

  3. onCreateView(LayoutInflater, ViewGroup, Bundle)方法用于创建和返回跟Fragment关联的View对象;

  4. onActivityCreate(Bundle)方法会告诉Fragment对象,它所依附的Activity对象已经完成了Activity.onCreate()方法的执行;

  5. onStart()方法会让Fragment对象显示给用户(在包含该Fragment对象的Activity被启动后);

  6. onResume()会让Fragment对象跟用户交互(在包含该Fragment对象的Activity被启恢复后)。

  二、Fragment对象不再使用时,要反向回调的方法:

  1. 因为Fragment对象所依附的Activity对象被挂起,或者在Activity中正在执行一个修改Fragment对象的操作,而导致Fragment对象不再跟用户交互时,系统会调用Fragment对象的onPause()方法;

  2. 因为Fragment对象所依附的Activity对象被终止,或者再Activity中正在执行一个修改Fragment对象的操作,而导致Fragment对象不再显示给用户时,系统会调用Fragment对象的onStop()方法。

  3. onDestroyView()方法用于清除跟Fragment中的View对象关联的资源;

  4. Fragment对象的状态被最终清理完成之后,要调用onDestroy()方法;

  5. 在Fragment对象不再跟它依附的Activity关联的时候,onDetach()方法会立即被调用


三、 Frament 管理

要管理 fragment,需使用 FragmentManager,要获取它,需在 activity 中调用方法 getFragmentManager()。 可以用 FragmentManager 来做以上事情:
使用方法 findFragmentById()或 findFragmentByTag(),获取 activity 中已存在的 fragment
使用方法 popBackStack()从 activity 的后退栈中弹出 fragment(这可以模拟后退键引发的动作)

用方法 addOnBackStackChangedListerner()注册一个侦听器以监视后退栈的变化
还可以使用 FragmentManager 打开一个 FragmentTransaction 来执行 fragment 的事务,比如添加或删除 fragment。

在 activity 中使用 fragment 的一个伟大的好处是能跟据用户的输入对 fragment 进行添加、删除、替换以及执行 其它动作的能力。提交的一组 fragment 的变化叫做一个事务。事务通过 FragmentTransaction 来执行。还可以把每个 事务保存在 activity 的后退栈中,这样就可以让用户在 fragment 变化之间导航(跟在 activity 之间导航一样)。

可以通过 FragmentManager 来取得 FragmentTransaction 的实例,如下:
FragmentManagerfragmentManager = getFragmentManager();
FragmentTransactionfragmentTransaction =fragmentManager.beginTransaction(); 一个事务是在同一时刻执行的一组动作(很像数据库中的事务)。可以用 add(),remove(),replace()等方法构成事

务,最后使用 commit()方法提交事务。在调用 commint()之前,可以用 addToBackStack()把事务添加到一个后退栈中, 这个后退栈属于所在的 activity。有了它,就可以在用户按下返回键时,返回到 fragment 执行事务之前的状态。如 下例:演示了如何用一个 fragment 代替另一个 fragment,同时在后退栈中保存被代替的 fragment 的状态。

//Create new fragment and transaction
Fragment newFragment = newExampleFragment();
FragmentTransaction transaction=getFragmentManager().beginTransaction();

//Replace whatever is in the fragment_container view with thisfragment, //and add the transaction to the backstack
t ransact ion.rep lace(R.id.fra gm ent _cont ainer,new Fra gment );

transaction.addToBackStack(null) ;

//Commit the transaction transaction.commit();

解释:newFragment 代替了控件 IDR.id.fragment_container 所指向的 ViewGroup 中所含的任何 fragment。然后调 用 addToBackStack(),此时被代替的 fragment 就被放入后退栈中,于是当用户按下返回键时,事务发生回溯,原先 的 fragment 又回来了。

如果向事务添加了多个动作,比如多次调用了 add(),remove()等之后又调用了 addToBackStack()方法,那么所有 的在 commit()之前调用的方法都被作为一个事务。当用户按返回键时,所有的动作都被反向执行(事务回溯)。

事务中动作的执行顺序可随意,但要注意以下两点:
必须最后调用 commit()
如果添加了多个 fragment,那么它们的显示顺序跟添加顺序一至(后显示的覆盖前面的) 如果在执行的事务中有删除 fragment 的动作,而且没有调用 addToBackStack(),那么当事务提交时,那些被删

除的 fragment 就被销毁了。反之,那些 fragment 就不会被销毁,而是处于停止状态。当用户返回时,它们会被恢复。 但是,调用 commit()后,事务并不会马上执行。它会在 activity 的 UI 线程(其实就是主线程)中等待直到线程 能执行的时候才执行(废话)。如果必要,可以在 UI 线程中调用 executePendingTransactions()方法来立即执行事务。

但一般不需这样做,除非有其它线程在等待事务的执行。
注意:只能在 activity 处于可保存状态的状态时,比如 running 中,onPause()方法和 onStop()方法中提交事务, 否则会引发异常。这是因为 fragment 的状态会丢失。如果要在可能丢失状态的情况下提交事务,请使用 commitAllowingStateLoss()。

四、 Fragment 与 Activity 通讯

目录

1、onAttach(Activity activity)

3、onCreateView()

4、onActivityCreated()

5、onStart()

6、onResume()

7、onPause()

8、onStop()

9、onDestroyView()

10、onDestroy()

11、onDetach()

  一、显示Fragment时(跟用户交互)要调用的核心的生命周期方法如下:

  二、Fragment对象不再使用时,要反向回调的方法:

三、 Frament 管理

四、 Fragment 与 Activity 通讯


尽管 fragment 的实现是独立于 activity 的,可以被用于多个 activity,但是每个 activity 所包含的是同一个 fragment 的不同的实例。Fragment 可以调用 getActivity()方法很容易的得到它所在的 activity 的对象,然后就可以查找 activity 中的控件们(findViewById())。例如:
ViewlistView =getActivity().findViewById(R.id.list);同样的,activity 也可以通过 FragmentManager 的方 法查找它所包含的 frament 们。

例如:

Examp leFra gment
fragment =(ExampleFragment)getFragmentManager().findFragmentById(R.id.example_fragment )

有时,可能需要 fragment 与 activity 共享事件。一个好办法是在 fragment 中定义一个回调接口,然后在 activity 中实现之。例如,还是那个新闻程序的例子,它有一个 activity,activity 中含有两个 fragment。fragmentA 显示新闻标题,fragmentB 显示标题对应的内容。fragmentA 必须在用户选择了某个标题时告诉 activity,然后 activity 再告诉 fragmentB,fragmentB 就显示出对应的内容。

如下例,OnArticleSelectedListener 接口在 fragmentA 中定义:

public static class FragmentA extends ListFragment{ //Container Activity must implement this interface

public interface OnArticleSelectedListener{
public void onArticleSelected(Uri articleUri);

}

然后 activity 实现接口 OnArticleSelectedListener,在方法 onArticleSelected()中通知 fragmentB。当 fragment 添加到 activity 中时,会调用 fragment 的方法 onAttach(),这个方法中适合检查 activity 是否实现了

 
OnArticleSelectedListener 接口,检查方法就是对传入的 activity 的实例进行类型转换,如下所示:

public static class FragmentA extends ListFragment{ OnArticleSelectedListenermListener;
...
@Override

public void onAttach(Activity activity){ super.onAttach(activity);
try{
mListener =(OnArticleSelectedListener)activity; }catch(ClassCastException e){
throw new ClassCastException(activity.toString()+"must implement OnArticleSelectedListener"); }

}

如果 activity 没有实现那个接口,fragment 抛出 ClassCastException 异常。如果成功了,mListener 成员变 量保存 OnArticleSelectedListener 的实例。于是 fragmentA 就可以调用 mListener 的方法来与 activity 共享事 件。例如,如果 fragmentA 是一个 ListFragment,每次选中列表的一项时,就会调用 fragmentA 的 onListItemClick() 方法,在这个方法中调用 onArticleSelected()来与 activity 共享事件,如下:
public static class FragmentA extends ListFragment{
OnArticleSelectedListenermListener;
...
@Override
public void onListItemClick(ListViewl,Viewv,intposition,long id){
//Append the clicked item's row ID with the content provider Uri
Uri noteUri =ContentUris.withAppendedId(ArticleColumns.CONTENT_URI,id); //Send the event and Uri to the host activity mListener.onArticleSelected(noteUri);

}
onListItemClick()传入的参数 id 是列表的被选中的行 ID,另一个 fragment 用这个 ID 来从程序的

  1. ContentProvider 中取得标题的内容。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值