Android面试——Fragment相关

来源:互联网 发布:詹姆斯深蹲力量数据 编辑:程序博客网 时间:2024/05/21 22:22

一、什么是Fragment,为什么它会被称为第五大组件

Fragment是一个模块化和可重用的组件, 目的是为了解决不同屏幕分辩率的动态和灵活UI设计。
Fragment之所以被称为第五大组件是因为它比Activity更节省内存,其切换模式也更加舒适,使用频率不低于四大组件,且有自己的生命周期,但是必须依附于Activity。
Fragment的优点可以具体整理为如下几点:

  1. Fragment 可以将 Activity 分离成多个可重用的组件,每个都有它自己的生命周期和 UI。

  2. Fragment可以轻松得创建动态灵活的 UI 设计,可以适应于不同的屏幕尺寸。从手机到平板电脑,在不同的安卓设备上统一你的UI。

  3. Fragment是一个独立的模块,紧紧地与 activity 绑定在一起。可以运行中动态地移除、加入、交换等。

  4. Fragment 解决 Activity 间的切换不流畅,轻量切换
  5. Fragment 替代 TabActivity 做导航,性能更好

二、阐述一下Fragment的生命周期

官方的生命周期图说明了一切:
这里写图片描述

FragmentActivity中启动,两者的的生命周期:
这里写图片描述

三、Fragment的添加方式

1.静态添加:在xml文件中指定name属性为Fragment

<fragment        android:name="com.baidu.fragmentdemo.BlankFragment"        android:layout_width="match_parent"        android:layout_height="wrap_content"/>

2.动态添加:

  1. 需要在xml文件中指定一个FrameLayout,设置ID,充当Fragment的占位布局
  2. 在java代码中获取FragementManager对象,是一个Fragment的声明周期管理者
  3. 通过FragmentManager启动一个事务FragmentTransaction
  4. 通过FragmentTransaction对碎片进行一系列的操作:add/remove/hide/show
    5.调用FragmentTransaction.commit()提交事务

3.注意事项:

  1. 同一个Fragment对象只能被add一次
  2. 同一个FragmentTransaction只能提交一次
  3. transaction.addToBackStack(null); //将事务添加到返回栈中,此时按back键不会直接退出程序,先进入上一个碎片

四、Fragment的replce、add、remove分别是什么作用,replace 和 add方法有什么区别?

  • replce:替换Fragment的栈顶页面
  • add:添加Fragment到栈顶页面
  • .remove:移除Fragment栈顶页面

replace 和 add方法的区别:

Fragment本身并没有replace和add方法, 这里的理解应该为使用FragmentManager的replace 和 add 两种方法切换Fragment时有什么不同。

  1. Fragment 的容器是一个 FrameLayout,add 的时候是把所有的 Fragment 一层一层的叠加到了 FrameLayout上了, 而replace的话首先将该容器中的其他Fragment去除掉然后将当前Fragment 添加到容器中。
  2. 一个 Fragment 容器中只能add一个 Fragment 种类,如果多次添加则会报异常,导致程序终止, 而 replace 则无所谓,随便切换。
  3. 因为通过 add 的方法添加的 Fragment,每个 Fragment 只能添加一次,因此如果要想达到切换效 果需要通过 Fragment 的的 hide 和 show 方法结合者使用。将要显示的 show 出来,将其他 hide 起来。这个过程Fragment的生命周期没有变化。
  4. 通过 replace 切换 Fragment,每次都会执行上一个 Fragment 的 onDestroyView,新 Fragment 的 onCreateView、onStart、onResume 方法。

五、Fragment 跟 Activity 之间是如何通信的?

Fragment向Activity传值:

第一种方法:在Fragment中法,通过getActivity(). 调用Activity中的公开方法;
第二种方法:在Fragment中定义一个内部回调接口,再让包含该Fragment的Activity类实现这个接口,这样Fragment就能够调用这个回调方法,将数据传给Activity。

Activity向Fragment传值:

第一种方法:在Activity中调用Fragment的方法, getFragmentManager().findFragmentById(R.id.xxx);
第二种方法:创建Bundle数据包,并调用Fragment对象的setArguments方法, 之后在Fragment类中调用getArguments

Fragment向Fragment传值:

第一种方法:通过宿主Activity调用另一个Fragment中的方法,getActivity().getFragmentManager().findFragmentById();
第二种方法:接口回调,在F1里面定义接口,Activity里面实现接口。通过回调实现F1与其父亲Activity的通信。在Activity接口回调方法里与F2通信,将参数传给F2;
第三种方法:使用广播,F1中将数据放在广播中发送,F2中接受广播,获取数据。

六、Fragment 如何实现类似 Activity 栈的压栈和出栈效果的?

Fragment 的事务管理器内部维持了一个双向链表结构,该结构可以记录我们每次 add 的 Fragment和 replace 的 Fragment, 然后当我们点击 back 按钮的时候会自动帮我们实现退栈操作

七、FragmentPagerAdapter与FragmentStatePagerAdapter区别

FragmentPagerAdapter在生命周期Destroy方法中调用的是detach方法,只是将Fragment的UI和activity的UI锁脱离开来,并不回收内存,所以它适用页面较少的情况

FragmentStatePagerAdapter在生命周期Destroy方法中条用的是remove方法,在每次切换viewPager时回收内存,真正的释放了内存,所以它适用页面较多的情况,更节省内存

原创粉丝点击