美文网首页
Android学习笔记之Fragment

Android学习笔记之Fragment

作者: sssssss_ | 来源:发表于2018-10-19 09:59 被阅读0次

    1.Fragment 是什么?

    Fragment 是 Android 自 3.0 版本开始引入的一种可以嵌入在 Activity 当中的UI片段,主要是为了能在不同分辩率屏幕上进行更为动态和灵活的UI设计,让程序更加合理和充分利用大屏幕空间。

    2.Fragment 为什么被称为第五大组件

    1. 使用频率高;
    2. 有自己的生命周期;
    3. 可以灵活加载到Activity中;
    4. 虽然有自己的生命周期,并不像 Activity 那样独立的,需要依附 Activity。

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

    • 静态加载:作为XML标签添加到 Activity 的布局文件当中。

    步骤1:新建fragment.xml文件
    步骤2:在Fragment中,重写onCreateView方法,为Fragment设置xml布局文件,转换成view对象返回。

    //传递三个参数:
    //LayoutInflater inflater表示布局填充器或者加载器,将xml文件转换成view对象。
    //ViewGroup container表示fragment插入activity的布局视图对象。
    //Bundle saveInstanceState表示存储上一个fragment的信息。
    View view = inflater.inflate(R.layout.fragment,container,false);
    return view;
    

    步骤3:在activity布局中,通过fragment标签引入fragment,记住是name属性

    <fragment
        android:name="com.songsong.FragmentTest.fragment"
        ...
    />
    
    • 动态加载:动态在 Activity 中添加 Fragment 。 (常用)
    //前提1:先创建 Fragment类并继承 Fragment,在onCreateview设置XML布局文件。
    //前提2:在Activity的XML布局文件中准备好布局容器R.id.lin_id
    
    //步骤1:创建Fragment的管理器对象FragmentManager 
    FragmentManager manager = getFragmentManager();
    //步骤2:获取Fragment的事务对象并且开启事务
    FragmentTransaction transaction = manager.beginTransaction();
    //步骤3:调用事务中相应的动态操作Fragment的方法执行,add、remove和replace
    transaction.add(R.id.lin_id, new Fragment1());
    //模拟返回栈
    transaction.addToBackStack(null);
    //步骤4:提交事务
    transaction.commit();
    

    4.Fragment 和 Activity 之间的通信

    通常,Fragment 与 Activity 通信存在三种情形:

    • Activity 操作内嵌的 Fragment,
    • Fragment 操作宿主 Activity,
    • Fragment 操作同属 Activity中的其他 Fragment。
    • 在 Activity 中调用 Fragment 中的 findFragmentById 方法;
    //通过FragmentManage的findFragmentById得到实例,然后就可以调用fragment里的方法
    RightFragment rf = getFragmentManager().findFragmentById(R.id.right_fragment);
    
    • 在 Fragment 中调用 Activity 中的 getActivity 方法;
    //fragment中调用Activity的方法,getActivity本身就是一个Context对象。
    MainActivity act = getActivity();
    
    • Fragment 与 Fragment 之间的通信:
      先在一个碎片中可以得到与它相关联的活动,然后再通过这个活动去获取另外一个碎片的实例,这样实现了不同碎片之间的通信了 。

    5.Fragment 的生命周期

    Fragment生命周期

    简单的Fragment流程图—— onAttach->onCreate -> onCreateView -> onActivityCreated -> onStart -> onResume ->创建成功-> onPause->onStop->onDestroyView -> onDestroy->onDetach。其中和Activity有不少名称相同作用相似的方法,而不同的方法有:

    • onAttach():当Fragment和Activity建立关联时调用
    • onCreateView():当Fragment创建视图时调用
    • onActivityCreated():当与Fragment相关联的Activity完成onCreate()之后调用
    • onDestroyView():在Fragment中的布局被移除时调用
    • onDetach():当Fragment和Activity解除关联时调用

    Fragment操作生命流程图:

    • 打开 Fragment:onAttach->onCreate->onCreateView->onActivityCreated->onStart->onResume
    • 替换 Fragment:onPause->onStop->onDestroyView
    • 返回旧 Fragment:onCreateView->onActivityCreated->onStart->onResume
    • 退出 Fragment:onPause->onStop->onDestroyView->onDestroy->onDetach

    6.FragmentPagerAdapter 与 FragmentStatePagerAdaper 区别:

    • FragmentPagerAdapter :FragmentPagerAdapter 在切换 ViewPager 的时候,只是把 Fragment的UI 与 Activity的UI 脱离开来,并不回收内存。所以它适用页面较少的情况。(在其源码 DestroyItem 方法中的最后一行,mCurTransaction.detach 可知)

    • FragmentStatePagerAdaper :由于 FragmentStatePagerAdaper 在每次切换 ViewPager 的时候,它是回收内存的。又因为在页面较多的情况下会更耗内存,所以它适合页面较多的情况。(在源码 DestroyItem 方法中的最后一行,mCurTransaction.remove 可知 )

    7.Fragment 的 replace、add、remove 方法

    • replace 是 FragmentManager 的方法,是将 Activity 最上层的 Fragment 替换掉。
    • add 将 Fragment 的实例添加到 Activity 的最上层
    • remove 将 Fragment 的实例从 Activity 的队列中删除

    8.Fragment 特点

    • Fragment 可以作为 Activity 界面的一部分组成出现;
    • 可以在一个 Activity 中同时出现多个 Fragment,并且一个 Fragment 也可以在多个 Activity 中使用;
    • 在 Activity 运行过程中,可以添加、移除或者替换 Fragment;
    • Fragment 可以响应自己的输入事件,并且有自己的生命周期,它们的生命周期会受宿主 Activity 的生命周期影响。
    • Fragment 可以轻松得创建动态灵活的 UI 设计,可以适应于不同的屏幕尺寸。从手机到平板电脑。
    • Fragment 解决 Activity 间的切换不流畅,轻量切换。
    • Fragment 替代 TabActivity 做导航,性能更好。
    • Fragment 做局部内容更新更方便,原来为了达到这一点要把多个布局放到一个 activity 里面,现在可以用多 Fragment 来代替,只有在需要的时候才加载 Fragment,提高性能。

    9.Activity和Fragment的异同?

    • Activity和Fragment的相似点在于,它们都可包含布局、可有自己的生命周期,Fragment可看似迷你活动。
    • 不同点是,由于Fragment是依附在Activity上的,多了些和宿主Activity相关的生命周期方法:如onAttach()、onActivityCreated()、onDetach();另外,Fragment的生命周期方法是由宿主Activity而不是操作系统调用的,Activity中生命周期方法都是protected,而Fragment都是public,也能印证了这一点,因为Activity需要调用Fragment那些方法并管理它。

    10.怎么理解Activity和Fragment的关系?

    • 正如Fragment的名字“碎片”,它的出现是为了解决Android碎片化 ,它可作为Activity界面的组成部分,可在Activity运行中实现动态地加入、移除和交换。
    • 一个Activity中可同时出现多个Fragment,一个Fragment也可在多个Activity中使用。
    • 另外,Activity的FragmentManager负责调用队列中Fragment的生命周期方法,只要Fragment的状态与Activity的状态保持了同步,宿主Activity的FragmentManager便会继续调用其他生命周期方法以继续保持Fragment与Activity的状态一致。

    11.何时会考虑使用Fragment?

    • 用两个Fragment封装两个界面模块,这样只使一套代码就能适配两种设备,达到两种界面效果;(新闻列表、新闻内容)
    • 单一场景切换时使用Fragment更轻量化,如ViewPager和Fragment搭配使用。

    12.Activity向引入的Fragment传值

    • 步骤1:Activity中创建Fragment对象,调用setArguments(Bundle)方法存储值。
    • 步骤2:Fragment中调用getArguments()获取传递Bundle对象解析获取具体值。
    存储值 获取值

    13.Fragment向Activity传值

    步骤1:Fragment 中定义传值的回调接口,在生命周期 onAttach() 方法中获取接口的实现。

    private MyListener listener;
    @Override
    public void onAttach(...){
       ...
       listener = (MyListener)getActivity();
    }
    public interface MyListener{
       public abstract void sendMessage(String str);
    }
    

    步骤2:Fragment 需要传值的位置调用接口回调方法传值。

    listener.sendMessage(info);
    

    步骤3:Activity 实现回调接口重写回调方法获取传递的值。

    @Override
    public void sendMessage(String str){
      if(null !=str && !"".equals(str)){
        //显示处理
        }
    }
    

    14.Fragment与Fragment之间的传值

    fragment.jpg

    13.遇到过哪些关于Fragment的问题,如何处理的?

    • getActivity()空指针:这种情况一般发生在在异步任务里调用getActivity(),而Fragment已经onDetach(),此时就会有空指针,解决方案是在Fragment里使用 一个全局变量mActivity,在onAttach()方法里赋值,这样可能会引起内存泄漏,但是异步任务没有停止的情况下本身就已经可能内存泄漏,相比直接crash,这种方式显得更妥当一些。

    • Fragment视图重叠:在类onCreate()的方法加载Fragment,并且没有判断saveInstanceState==null或if(findFragmentByTag(mFragmentTag) == null),导致重复加载了同一个Fragment导致重叠。(PS:replace情况下,如果没有加入回退栈,则不判断也不会造成重叠,但建议还是统一判断下)

    @Override 
    protected void onCreate(@Nullable Bundle savedInstanceState) {
    // 在页面重启时,Fragment会被保存恢复,而此时再加载Fragment会重复加载,导致重叠 ;
        if(saveInstanceState == null){
        // 或者 if(findFragmentByTag(mFragmentTag) == null)
           // 正常情况下去 加载根Fragment 
        } 
    }
    

    Fragment状态保存 startActivityForResult 是哪个类的方法,在什么情况下使用?

    本文参考资料:

    相关文章

      网友评论

          本文标题:Android学习笔记之Fragment

          本文链接:https://www.haomeiwen.com/subject/xlfyzftx.html