2012-03-22 54 views
63

使用Fragment比使用在不同布局中重复使用的定制View有什么优势?为什么使用碎片?

original blog post introducing fragments,戴安娜Hackborn说

[片段]让开发者更容易编写能够在该平台秤在各种屏幕尺寸的 ,超越设施已经 可用的应用程序。

她继续在为应用程序制作平板电脑布局的情况下解释片段,该应用程序结合了来自同一应用程序的电话版本的两个活动的UI。

但似乎可以使用自定义视图实现相同的重用。片段和视图之间的主要不同似乎是他们具有不同的生命周期...

Fragment生命周期:

onAttach()onCreate()onCreateView()onActivityCreated()onStart()onResume()onPause()onStop()onDestroyView()onDestroy()onDetatch()

View生命周期:

ctoronFinishInflate()onAttachedToWindow()onMeasure()onLayout()onDetatchedFromWindow()

我想从开发人员听到有经验写什么好处大的应用程序(如果有的话),他们”在使用片段vs自定义视图将UI分解为可重用片段方面见过。

回答

51

主要原因是片段比自定义视图更可重用。

有时您不能单独依靠视图创建完全封装的UI组件。这是因为有些东西是你想放进你的视图中的,但是不能,因为只有一个Activity可以处理它们,因此强制活动和视图之间的紧密耦合。

这是一个这样的例子。比方说,你想创建一个可重用的UI组件,在很多事情中,它们都想要捕获一张照片并对其进行处理。传统上,您会启动启动相机并随捕获的图像一起返回的意图。

请注意,您的自定义UI组件不能完全封装这一功能,因为它必须依靠主办活动的startActivityForResult因为意见不接受活动结果(他们可以间接地烧透方面的意图)。

现在,如果您想在不同的活动中重复使用自定义UI组件,那么您将重复Activity.startActivityForResult的代码。

片段另一方面干净地解决这个问题。

同样,您的片段可以将项目添加到您的选项菜单中,传统上只有一个活动可以完成。如果您的自定义视图的状态决定了菜单中的内容,这也可能很重要。

+0

很好的答案,在我找到你之前,必须通过3-4个类似的SO帖子。 – 2015-01-27 07:25:28

+0

“同样,你的片段可以贡献项目到你的选项菜单,”@numan如果你解释这一点,这将是很大的帮助\ – Killer 2015-10-28 09:41:26

31

片段不仅仅是一个视图。事实上,它甚至可以完全没有看法。它可以包含各种各样的东西,包括AsyncTasks,各种监听器,文件和数据库访问等等。

将其视为一项小型活动,但您可以在屏幕上使用它们中的多个,并与它们一起工作,包括在可见时与对方通信。

E.g.您可以在一个片段中显示购物车列表,并在另一个片段中详细显示当前选定的购物车。然后,例如,更改详细视图中项目的数量,并可以通知列表视图并更新列表视图中的总价格。您可以完全协调像这样的交互,例如,仍然只有其中一个在较小的屏幕设备上可见。

我重构了一个大型商业应用程序(> 15个活动)从活动到片段以获得良好的平板电脑支持,我永远不会开始一个没有片段的新应用程序。

更新2016年2月虽然上述情况仍然如此,但碎片的复杂性导致许多人完全避免使用它们。较新的模式,如使用MVC方法和更强大的视图提供了替代方案。正如他们所说...... YMMV。

+13

但我可以使用自定义视图来实现您刚才给出的示例。您可以让视图彼此通信,并检查操作系统是否正在使用平板电脑或电话布局。我看到人们用碎片做同样的事情。用碎片而不是视图实现它有什么好处? – VIBrunazo 2012-08-21 19:37:47

+0

也许片段提供更多的支持过渡,动画,并强制一些容器,如ViewPager,ActionBar和Tabs .. – Snicolas 2013-02-04 19:12:49

+1

@VIBrunazo在下面看到我的答案。 http://stackoverflow.com/a/14912608/909956 – 2013-02-16 16:44:50

0

自定义视图比仅使用片段代替您的活动更有效。如果您决定使用活动和自定义视图,则必须创建自定义视图,然后必须在活动中实施相同的活动生命周期方法(对于片段使用非常类似的生命周期)。

使用片段还允许您将组件分离到它们自己的类(片段)中,而不是在单个活动中包含太多逻辑。让我以一个例子为例:

假设您正在实施杂志阅读器应用程序。使用片段,您可以创建一个片段:ArticleList(其中显示文章列表)和另一个片段:ArticleDisplay,它处理显示内容的逻辑。然后您可以指定这些片段应如何使用片段工具进行交互,以便在手持设备上,您可以使用全屏幕实时显示ArticleDisplay,而在平板电脑上,您可以并排显示片段。

如果您尝试使用活动/自定义视图,您将在整体活动中拥有这两个碎片的逻辑,您必须编写自定义视图,并且您必须调试这个笨拙的怪物。

片段通常是编写应用程序的更复杂和更强大的方式。他们可以做一切活动可以做的事情,等等。如果你不需要额外的功能,默认设置可能会让你需要去的地方,而且工作量较少。

+2

就整体活动而言,为什么使用Fragments将控制器代码简单地分解为其他POJO控制器类? – avh 2012-03-22 17:27:16

+0

这对Fragment中包含的逻辑起作用(并且您可能应该为这两个活动和碎片执行此操作),但是您仍遇到单个方法调用作为(至少)两个控件的入口点的问题流动,这是最好的分离出来。你只能覆盖Android用来与你的类在一个地方进行通信的方法调用,所以如果你有一个单一的活动,你有一个OnCreateDialog()被调用两组对话框,每个“屏幕”一个。 – 2012-03-22 17:32:13

+0

我还应该补充说,使用Fragment而不是Activity不会有任何缺点。这很可能不需要编写任何额外的代码来获得与使用片段的Activity相同的行为,并且如果您需要 – 2012-03-22 17:33:59

3

生命周期方法可能是您最大的暗示。如果你仔细想想,它们与活动生命周期密切相关(对活动和视图有一些挂钩)。事实上,你链接的文章中,Hackborn说:

在你能想到的一个片段作为一个小型的活动

与软件设计/开发很多东西从某种角度来说,也有多种方式来做事情。有很多不同的地方你可以把你的代码。是的,你可能会把很多东西放在一个视图中,但是把不同的关注点分开放在不同的类中是件好事。这种经典模式是MVC,适用于这种情况。你不想在你的视图中使用太多的控制器逻辑。最好将它保存在类似控制器的类中,这些类是活动和现在的片段。这就是为什么片段的生命周期更像活动而不是视图 - 它是为了促进这种组织而制作的。

+2

似乎片段和活动都在MVC中扮演控制器的角色。为什么不使用POJO类作为分割控制器而不是片段的方式? – avh 2012-03-22 17:28:41

6

一些介绍:

想象活动作为保持一个大蛋糕板。 片段将是一个容器,将同一块蛋糕切成块。 每片包含它自己的逻辑(听众等)。 总的来说,它们与一个大蛋糕几乎没有区别。

好处:

  1. 当板无法容纳一个大蛋糕。 (屏幕很小)您可以轻松使用一些板块(活动)来保存每个板块,而无需将您的逻辑移动到新活动中。

  2. 更好的重用性。我有一些实例可以在另一个App中完全重用一个片段。您可能会声称自定义视图也可以这样做。但请参考第1点,我可以重新使用它,只需要几行布局更改,但对于自定义视图,它必须找到一种方法将其插入到布局和代码中。

  3. 从某种意义上说,这是在Android编程中组织UI逻辑的更多OO方法。当你有一个功能(例如屏幕上的一个新分区)时,你可以创建一个新的Fragment类,并对现有的活动类进行微小的修改。但是,如果您只在活动中进行编程,则需要添加逻辑并对受测试的类进行大的修改。

只是我2美分。 :)

+1

但是,您可以轻松地将逻辑封装在每片蛋糕中,而不需要使用片段。我可以做一个很好的干净的活动,只会有一两行代码创建和实现一块蛋糕。所有的逻辑将在蛋糕类 – jonney 2013-05-02 17:10:51

+0

因此,所有的碎片都只是一种** XML与相关的Java源代码**,并有一个独立于外部世界的包内?除此之外,我的意思是,如果我们可以想象一个情况,那就是从源代码创建的图形,我们可以使用常规的类。 *顺便说一下,在Scala中,有一种非常好的方法可以通过使用特性来解决这些问题!* – 2014-03-23 14:51:14

+0

这个问题实际上是关于片段vs视图,而不是片段与活动。 – user3614314 2015-06-05 16:25:36

0

我碰过一次碎片,发现它们不是很有用(请参阅this post)。根据我读到的,片段对于可以访问活动环境的对象来说确实是一个奇特的词。我喜欢在我的工作中忽略碎片,并自己创建这些对象。我通过向构造函数传递Activity而不是Context来创建非常大且要求非常苛刻的应用程序。然而,使用Fragments的一个主要好处是它们受到View布局系统的支持 - 因此您可以轻松将它们添加到Android xml(如果您将它用于布局)。