Android——Fragment学习笔记

Fragment学习笔记

 

Fragment介绍:Segment your app into multiple, independent screens that are hosted within an Activity.

 

Fragment生命周期:四个状态和回调方法;

四个状态:

  • 运行状态:Fragment为可见的,并且它所关联的活动正处于运行状态,该Fragment也处于运行状态;
  • 暂停状态:当可见的Fragment所关联的活动进入暂停状态时(由于另一个未占满屏幕的活动被添加到栈顶),Fragment也会进入暂停状态;
  • 停止状态:当Fragment所关联的活动进入停止状态时,它也进入停止状态,或者被FragmentManager的remove()、replace()方法从活动中移除,如果在事务提交之前调用了addToBackStack()方法,那么会进入停止状态,如果没有那么会继续进入后面的销毁状态,进入停止状态的Fragment对用户来说是完全不可见的,有可能被系统回收;
  • 销毁状态:当Fragment所关联的活动被销毁时,它也会进入销毁状态,或者被FragmentManager的remove()、replace()方法从活动中移除并且没有调用addToBackStack()方法。

活动中有的回调方法Fragment都有,还有5个附加的回调方法:

  • onAttach():当Fragment和活动建立关联的时候调用;
  • onCreateView():为Fragment创建视图(加载布局)时调用。
  • onActivityCreated():确保与Fragment相关联的活动一定已经创建完毕的时候调用。这个方法将要被废弃了!
  • onDestroyView():当与Fragment关联的视图被移除的时候调用;
  • onDetach():当Fragment和活动解除关联的时候调用;

 

Fragment完整生命周期示意图:

 

 

 

FragmentManager:用来管理Fragment,在activity中需要先使用getFragmentManager()或getSupportFragmentManager()(这个用于support包的fragment,向下兼容,现api28后变成support包全部转为Androidx)来获取到FragmentManager,如果在fragment中则可以先getactivity()获取到其依赖的activity;获取在fragment中的fragmentmanager:getChildFragmentManager()这种情况用于fragment中嵌套fragment,同时子fragment可以通过getParentFragment()获得。

 

在Android中fragmentManager是以事务为单位来管理的,每次我们都通过fragmentManager.beginTransaction()来获得一个FragmentTransaction对象,然后进行添加,替换,删除等,最后commit提交,这整个过程从begin到commit进行的所有操作就是一个事务,每个commit提交一个事务。

事务中的操作

  • add()方法会直接将一个fragment添加到指定的id布局中,不管这个布局容器中原来有没有,无条件覆盖。所以会叠加,而之前的fragment只是被遮挡,view并不会被摧毁;
  • getFragmentbyTag()与getFragmentbyId()这两个方法可以获得有相应的tag或id属性的fragment(这两个属性也可以通过xml里布局设置),那么就出现了有多个fragment拥有相同的tag和id,那调用该方法获得的是哪个呢?实测获得的是最顶层的那个fragment,也就是最近添加的;
  • replace()该方法不同于add()可有其注释的出,relplace()会先相应调用该布局id容器中所有的add的fragment的remove()方法,然后在调用add()方法;
  • remove()移除这个fragment,最后会调用onDetach();
  • show()和hide() ,这里要注意调用这两个方法并不会走fragment的生命周期,这意味着并不会调用onPause(),onStop方法,而是只调用了onHiddenChanged()方法,所有改变应在这个方法里,重写之;
  • addToBackTrack()最后说一下fragment的回退栈,注意,只有在commit事务是调用了addToBackTrack()方法,才会有回退栈,才会在回退栈里添加,否则就没有回退栈,pop方法不会有任何改变。 addToBackTrack()即把本次事务的所有操作储存起来,注意调用了addtobaktrack后remove方法不会真的把fragment移除,而只是distroy了它的view,并没有调用onDetach(),也就是说它还连接在宿主中。
  • popbackTrack,该方法即将回退栈中的最近的一次事务pop出来,也就是反过来调用方法,add就是remove,remove就add,所以如果这个调用了replace,那么pop后就会将这个replace add的fragment移除,然后在把之前remove的所有fragment add到里面。而之前就存在的fragment依然存在,没有变化,就像是add覆盖到上面一样。所以加入回退栈后pop可以回到上次操作;

 

Fragment和Activity之间通信

在Activity中调用Fragment中的方法:FragmentManager提供了一个类似于findViewById()的方法,专门用于从布局文件中获取Fragment的实例,例如:

RightFragment rigthFragment = (RightFragment)getSupportFragmentManager().findFragmentById(R.id.right_fragment);

在Fragment中调用Activity中的方法:通过getActivity()方法来得到和当前碎片相关联的活动实例,例如:

MainActivity activity = (MainActivity)getActivity();

 

 

使用限定符large根据运行设备是手机还是平板来动态加载布局:

  1. 在res资源文件夹下创建一个人layout-large文件夹,限定符size选择large,然后在这个文件夹下创建一个和layout文件夹下要使用的布局一样名字的.xml文件;
  2. 在新创建的.xml文件中写运行设备为平板时的界面布局代码,原layout文件夹下写运行设备为手机时的界面代码;
  3. 写完后运行,运行设备屏幕被认为是large的设备会自动加载layout-large文件夹下的布局,小屏幕的会加载原layout文件夹下的布局。

除了large之外,判定设备屏幕大小的限定符还有:small、normal、xlager。

 

除了让系统自己判定外,还可以使用最小宽度限定符(Smallest-widthQualifier),它允许我们为加载当前文件夹下的布局的设备屏幕宽度设置一个最小值,如果不小于就可以使用,大于就加载另一个layout文件夹下的布局。如下图所示,设置最小宽度为600dp:

 

 

 

 

posted @ 2020-06-24 20:36  木霖  阅读(409)  评论(0编辑  收藏  举报