知识点
先说一下 Fragment,中文可以叫片段,其实我们也可以把它理解成一个组件,它有自己的生命周期(回调函数),可以组织UI和业务逻辑。但它不像 Android 的四大组件(Activity, Service, BroadcastReceiver和ContentProvider)那样可以独立存在,它必须要依附于 Activity,由 Activity 中的 FragmentManager 实例来管理它的生命周期。
Google 最初引入 Fragment 主要是为了给大屏幕(如平板电脑)上更加动态和灵活的 UI 设计提供支持,看一下下图你就明白了:
我们可以在多个 Activity 中重复使用某个片段,并且可以按我们的需求把不同的片段组合在一个界面中,好处显而易见,减少工作量提高了代码的可重用性。
也就是说每个片段是相互独立的,如上图所示,Fragment A 并不知道这个 Activity 中是否存在Fragment B。这样一来就会产生 Fragment 之间通信的问题(比如Fragment A点击了列表的一项,Fragment B的内容要进行更新),当然这个问题的答案并不是唯一的,有很多种做法。不过,最基础的做法你应该了解一下,就是通过 Activity 进行通信。
尽管 Fragment 是作为独立于Activity的对象实现,并且可在多个Activity内使用,但片段的给定实例会直接绑定到包含它的 Activity。具体地说,片段可以通过getActivity()访问 Activity 实例。
同样地,Activity 也可以使用 findFragmentById() 或 findFragmentByTag() ,通过从FragmentManager获取对Fragment的引用来调用片段中的方法。
知道这些基础,你应该很清楚怎么进行通信了。不过我们建议的方式是面向接口编程,在Fragment中getActivity获取到的Activity实例应该是实现了我们某个接口的实例,即在Fragment的代码中不应该出现某个具体的Activity类。
Fragment的生命周期
如果你喜欢使用Fragment,一定要清楚这些生命周期的方法,哪个方法会创建视图(View),哪个会销毁视图,这样才能更好的使用它们。
先来看看官方的Fragmenet生命周期和Activity生命周期的对应关系图:
是不是觉得,好像也没有多复杂,只是在一些对应的 Activity 生命周期方法上进行了细分。
我们再看看反对使用 Fragment 的人是如何看待 Fragment 的生命周期的:
是不是头都大了?简单地说Fragment的生命周期并不像官方描述的那样简单,感兴趣的朋友可以看看这篇文章:我为什么主张反对使用Android Fragment。
Fragment 虽然在某种程度上实现了代码复用,但并没有将 UI 和逻辑分离,而且引入了复杂的生命周期,在一定程度上也限制了它的使用。如 Fragment 嵌套 Fragment 可能会遇到嵌套的 Fragment 接收不到 onActivityResult 事件之类的问题。
不过,我也看到有人是这样使用 Fragment 的,创建一个没有 UI 的 Fragment 仅将它做为保存状态的工具使用。因为 Fragment 也有 onSaveInstanceState 方法,可以在里面对状态进行处理,而且系统回收Activity 后再使用 Activity 时会帮我们恢复 Fragment 的状态。
关于 Fragment 还有很多细节,如果面试者经常使用的话,还可以问问“如何管理Fragment回退栈”或者“FragmentTransaction中remove和detach的区别”等问题。
你的朋友是不是也在准备面试呢?你可以“请朋友读”,把今天的题目分享给好友,或许你能帮到他。