Android 你需要掌握的知识(三)

目录

Fragment.png

一.Fragment详解

一.Fragment基础

1.Fragment

Fragment为什么会出现,它其实是android3.0的时候引入的,可以翻译为“碎片” “片段”起初它主要是给大屏幕上设备上更灵活的展现UI所设计的。

图片来源于网络.png

如上图,左边展现的是平板电脑上的使用场景,而在实际项目开发中,使用频率更高的是右边的场景,右边的图中,左右两个Activity包含了各自的Fragment,Activity A通过 方法启动 Activity B时,实际上启动的是Fragment B。所以说我们一般会在一个Activity中嵌套多个Fragment,来进行UI 数组间的切换,一般用到的模式是Fragment+ViewPager。 Fragment相比Activity 更节省内存,同时UI的切换效果更加舒适, Fragment有自己的生命周期,同时它可以动态,灵活的加载Activity。但是Fragment并不是像Activity一样完全独立的,它虽然有自己的生命周期,但它必须依附Activity,同时它要加载到Activity当中。

2.Fragment加载到Activity的两种方式

1.静态添加:添加Fragment到Activity的布局文件当中
2.动态添加:动态在Activity中添加Fragment

静态加载就是把Fragment作为一个xml的标签加到Activity布局当中。

常用的方法就是动态添加
首先在布局文件中放一个FrameLayout,方便在Activity中可以动态添加不同的Fragment

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.bsoft.fragmentdemo.MainActivity">
    <FrameLayout
        android:id="@+id/fl_demo"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</RelativeLayout>

然后在Activity中动态添加Fragment

    //步骤1 : 添加FragmentTransaction的实例
    FragmentManager fragmentManager = getFragmentManager();
    FragmentTransaction transaction = fragmentManager.beginTransaction();

    //步骤2 :用add()方法加上Fragment的对象FirstFragment
     FirstFragment firstFragment = new FirstFragment();
     transaction.add(R.id.fl_demo,firstFragment);

     //步骤3 : 调用commit()方法使FragmentTransaction实例的改变生效。
     transaction.commit();
3.FragmentPagerAdapter与FragmentStatePagerAdapter区别

FragmentPagerAdapter适用于页面较少的情况。
FragmentStatePagerAdapter适用于页面较多的情况。

FragmentPagerAdapter源码中的destroyItem方法:

   @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        if (mCurTransaction == null) {
            mCurTransaction = mFragmentManager.beginTransaction();
        }
        if (DEBUG) Log.v(TAG, "Detaching item #" + getItemId(position) + ": f=" + object
                + " v=" + ((Fragment)object).getView());
        mCurTransaction.detach((Fragment)object);
    }

它最后一行调用的是 FragmentTransaction的detach方法。detach并不是真正的内存回收,它只是把Fragment的UI和Activity的UI脱离开来,并不回收内存。

FragmentStatePagerAdapter源码中的destroyItem方法:

 @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        Fragment fragment = (Fragment) object;

        if (mCurTransaction == null) {
            mCurTransaction = mFragmentManager.beginTransaction();
        }
        if (DEBUG) Log.v(TAG, "Removing item #" + position + ": f=" + object
                + " v=" + ((Fragment)object).getView());
        while (mSavedState.size() <= position) {
            mSavedState.add(null);
        }
        mSavedState.set(position, fragment.isAdded()
                ? mFragmentManager.saveFragmentInstanceState(fragment) : null);

        mFragments.set(position, null);
        //在这里
        mCurTransaction.remove(fragment);
    }

mCurTransaction.remove(fragment),在FragmentStatePagerAdapter里面是真正释放了fragment内存。所以说明了FragmentStatePagerAdapter比FragmentPagerAdapter更节省内存的。

二.Fragment生命周期

图片来源于网络.png
1.Fragment生命周期与Activity生命周期的对比
图片来源于网络.png
2.Fragment从启动到销毁生命周期全过程
Fragment从启动到销毁生命周期全过程.png

跟记忆Activity生命周期一样,Fragment的生命周期也需要灵活的来记忆

Fragment 创建时会调用:

onAttach() -> onCreate() -> onCreateView() -> onActivityCreated()

onAttach():在Fragment 与 Activity关联之后所回调的
onCreate() : 是在初次创建Fragment时候调用
注:这里的onCreate方法看起来和Activity中的onCreate方法一样。但是这个方法只是用来创建Fragment,此时的Activity还并没有被创建完成。
onCreateView():是系统在Fragment首次绘制用户界面时候调用的这个方法
注:如果想要为这个Fragment绘制UI界面,从该方法返回的View必须是Fragment布局的根视图。
在onCreateView()方法调用之后会调用onViewCreated()方法
onViewCreated():表明Fragment的UI界面已经完全绘制好了,调用这个方法可以初始化控件资源。
onActivityCreated():这个方法是在Activity的onCreat()方法调用之后才可以被调用。也就是在Activity被渲染绘制成功以后的调用方法

Fragment被用户可见后调用
onStart() -> onResume()

onStart():表示Fragment可见了
onResume():表示Fragment可以跟用户进行交互了(点击,滑动等操作)

到这里已经完成了Fragment从启动到展现的操作。

当要Fragment被销毁
onPause() -> onStop() -> onDestroyView() -> onDestroy() -> onDetach()

onPause():系统将此方法作为用户离开Fragment的第一个信号(但并不总是意味着此Fragment会被销毁)进行调用。 通常可以在此方法内确认在当前用户会话结束后仍然有效的任何更改(因为用户可能不会返回)。
onDestroyView():表示这个Fragment即将结束,会被保存。
onDetach():Fragment和Activity解除关联的时候调用

到此,我们完整的走完一Fragment的生命周期。

还有一些其他场景时Fragment调用的生命周期

屏幕灭掉
onPause() -> onSaveInstanceState() -> onStop()

屏幕解锁
onStart() -> onResume()

切换到其他Fragment
onPause() -> onStop() -> onDestroyView()

切换回本身的Fragment
onCreateView() -> onActivityCreated() -> onStart() -> onResume()

回到桌面
onPause() -> onSaveInstanceState() -> onStop()

回到应用
onStart() -> onResume()

三.Fragment通信

1.在Fragment中调用Activity中的方法

(getActivity)只要调用getActivity方法,就可以获取到Activity中的方法

2.在Activity中调用Fragment中的方法

(接口回调)在Fragment中创建个接口,然后由Activity实现。这样就能完成在Activity中调用Fragment中的方法

3.在Fragment中调用Fragment中的方法

(findFragmentById)首先可以通过 getActivity获取Activity的方法,然后通过findFragmentById获取到Activity所对应的另外一个Fragment的方法,这样就能完成Fragment与Fragment的通信

四.Fragment的replace,add,remove方法

replace():替换Fragment实例。
add():将一个Fragment实例添加到添加到Activity最上层
remove():将Fragment实例从Activity队列中删除

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,904评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,581评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,527评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,463评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,546评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,572评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,582评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,330评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,776评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,087评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,257评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,923评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,571评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,192评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,436评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,145评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,127评论 2 352

推荐阅读更多精彩内容

  • 最近刚从旧公司离职,为面试在做准备,因为平时开发CV大法用得比较多,很多基础知识掌握得不是很牢靠以及很多工具框架只...
    黎清海阅读 2,180评论 1 19
  • 开篇废话 公司搬迁告一段落,吐槽一句,从此就需要过上车程一个半小时的上下班之旅了。。。。。。 上一篇我们了解了四大...
    进击的欧阳阅读 847评论 1 9
  • 你若相信一切是最好的安排 风中的云也要为你起舞欢呼 你若相信一切是最好的安排 林中的小鸟也向你欣然高歌 你若相信一...
    一枝橄榄阅读 454评论 0 0
  • 把你的玻璃心收拾一下,继续上路
    罅02阅读 85评论 0 0