Fragment 深入理解——Fragment(一)

转载请标明出处:http://blog.csdn.net/xx326664162/article/details/54343942 文章出自:薛瑄博客

Fragment的基本用法,请查看官方文档:

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

也可以看这里
Android Fragment 真正的完全解析(上)
Android Fragment 真正的完全解析(下)

一、Fragment生命与Activity生命周期关系

下面看下Fragment的生命周期图:

这里写图片描述

Fragment的生命周期,看起来跟Activity很相似,一个关键的区别在于fragment的生命周期方法是由Activity托管的而不是操作系统调用的,因为操作系统无法得知Activity管理的fragment。

onViewCreated()就是上面的onActivityCreated()

1.1、Activity的FragmentManager负责调用队列中Fragment的生命周期方法。

  • 添加Fragment供FragmentManager管理时,onAttach(Activity)、onCreate(Bundle)以及onCreateView(…)方法会被调用。
  • Activity的onCreate(…)执行后,onActivityCreated(…)方法也会被调用。

1.2、Fragment真正意义上的onResume和onPause

Fragment虽然有onResume和onPause的,但是这两个方法是Activity的方法,调用时机是与Activity相同,就是说即使Fragment没有显示,但是他所在的activity显示了,Fragment的onResume依然会调用。

下面介绍三种情况,来检测Fragment是否处于显示状态

判断当前fragment是否对用户可见

(1)、ViewPager中嵌套fragment

由于ViewPager的预加载效应,当从页面1切换到页面2的时候,虽然页面3对于用户看不见,其实已经把页面3加载出来了,会调用页面3的onResume()方法,我们可以通过setUserVisibleHint()方法来判断当前fragment是否可见

@Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        try{
            if(getUserVisibleHint()){//界面可见时
                initReqUnreadNotice();
                getCacheSize();
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

注意此方法只会在不同fragment切换时才会调用,如果从fragment跳转到activity是不会调用此方法的,是不会调用setUserVisibleHint方法的,这时就要根据onResume和onPause方法来判断界面是否显示

(2)、使用replace加载或切换Fragment

使用Activity直接引入 或者通过FragmentManager的addFragment或replaceFragment动态载入,只要监听Fragment的onResume和onPause方法就能够判断其显隐。

@Override
    public void onResume() {
        super.onResume();
        updateUserState();
    }
@Override
    public void onPause() {
        super.onPause();
       //...
    }

(3)、通过show(Fragment)和hide(Fragment)加载或切换fragment

通过FragmentManager的showFragment和hideFragment加载fragment时,显示与隐藏fragment,隐藏fragment时并没有调用onPause()方法,这时需要根据onHiddenChanged方法来判断

 @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        if (hidden) {
           //隐藏状态
        } else {
           //显示状态
        }
    }

如果用户直接按home键退出了,程序没有对home按键事件进行监听,在按home键时调用hideFragment,那么onHiddenChanged事实上没有被调用,反而是onPause被调用了。所以我们需要针对这样的情况做特殊的处理。比如在home键退出时显示调用一下hideFragment或者在onPause中也发信号说本Fragment不可见了,这都是可以的。

1.3、在Activity处于停止,暂停或运行状态下时,添加Fragment会发生什么呢?

  • FragmentManager立即驱使Fragment快速跟上Activity的生命周期,直到与Activity的最新状态保持同步。例如,向处于运行状态的activity中添加fragment时,以下fragment生命周期方法会被依次调用:onAttach(Activity)、onCreate(Bundle)、onCreateView(…)、onActivityCreated(Bundle)、onStart(),onResume()方法。

  • 只要Fragment的状态与Activity的状态保持了同步,Activity的FragmentManager便会继续调用其他生命周期方法以继续保持Fragment与Activity的状态一致,而几乎就在同时,Activity接受到了从操作系统发出的相应调用。但Fragment方法究竟是在Activity方法之前还是之后调用的这一点却是无法保证的哦~

二、添加Fragment

官方文档:
Creating a Fragment
构建灵活的 UI

2.1、在运行时向 Activity 添加Fragment

如果您计划在 Activity 的生命周期内更改片段,如需执行添加或移除片段等事务,您必须使用 FragmentManager 创建 FragmentTransaction,后者将提供添加、移除、替换片段以及执行其他片段事务所需的 API。

FragmentManager

FragmentManager是负责管理fragment的,将fragment添加到activity视图层级结构中、移除、隐藏等等操作,都是通过这个类来进行的。

针对在一个Activity中的某个Layout中切换Fragment,两种方法:
1)使用replace方法把原有的Fragment替换掉;
2)使用hide和show方法,把已经添加过的Fragment再次显示出来。

这两种方法区别,以及其生命周期的调用,可参考下面两篇文章

[Android]Fragment加载替换add,show,hide,replace方法
从Fragment被销毁看replace和add的区别

2.2、布局文件中向 Activity 添加Fragment

在xml中使用 < fragment> 元素进行定义,这样添加的Fragment ,不能在运行时进行remove操作

三、Fragment 分类

分为android.app.Fragmentandroid.support.v4.app.Fragment,下面来详细讲解一下这两个类的区别

3.1、在Fragment中获取FragmentManager

只能使用FragmentManager()

3.2、在Activity 中获取FragmentManager 分下面两种情况

android.app.Fragment

这个类是在Android 3.0(API level 11)加入的,也就是说在Android 3.0以后的Activity,知道如何管理Fragment

1、使用getFragmentManager()获取 FragmentManager

android.support.v4.app.Fragment

为了使Android 3.0以前的系统,也能使用Fragment,在 Support Library 引入了Fragment。

使用该类需要注意两点:

1、Activity必须继承android.support.v4.app.FragmentActivity

2、使用getSupportFragmentManager()获取 FragmentManager

结论

使用哪个的Fragment,需要注意使用对应的Activity和获取FragmentManager方式。

如果Activity A所在app的targetSdkVersion是api 11及以上,并且运行在api 11及以上的系统上,那么它可以使用android.app.Fragment。如果Activity A也是继承自FragmentActivity,那么它也同时可以使用android.support.v4.app.FragmentActivity。

继承AppCompatActivity类

现在Android Studio 中新建的activity默认是继承AppCompatActivity,AppCompatActivity继承FragmentActivity,而现在大多数targetSdkVersion都是api 11及以上。所以可以同时使用这两种Fragment


你可能会说,既然有标准库了,为什么还要使用getSupportFragmentManager()

我就遇到这样的一个情况,比如使用ViewPager和FragmentPagerAdapter来加载显示Fragment,需要的就是FragmentManager(它的全包名android.support.v4.app.FragmentManager),虽然都是FragmentManager,不同的包名就是不同的类了

如果你知道标准库里有替代ViewPager的类,请在评论里告诉我

四、viewpage和Fragment结合使用

viewpage可是实现页面的左右滑动,viewpage的适配器PagerAdapter(里面有四个方法必须实现),包含了需要显示页面的数据(类似于ListView中的Adapter),在viewpage和Fragment结合使用的时候,有两个适配器FragmentPagerAdapter 和 FragmentStatePagerAdapter,它们继承了PagerAdapter。它们之间的差别参考下面第2个

1.Android ViewPager和Fragment实现顶部导航界面滑动效果

2.Android Fragment+ViewPager 组合,一些你不可不知的注意事项

下面两篇文章介绍了,ViewPager 和view的使用
3.ViewPager 全面剖析及使用详解

4.Android ViewPager使用详解


参考:
https://developer.android.com/training/basics/fragments/creating.html
浅谈FragmentManager与fragment之一二事
【Android】Fragment真正意义上的onResume和onPause
getFragmentManager与getChildFragmentManager,解决fragment白屏
Fragment 中setUserVisibleHint方法不执行

关注我的公众号,轻松了解和学习更多技术
这里写图片描述

发布了244 篇原创文章 · 获赞 799 · 访问量 234万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 代码科技 设计师: Amelia_0503

分享到微信朋友圈

×

扫一扫,手机浏览