【问题标题】:Why use Fragments? [duplicate]为什么要使用片段? [复制]
【发布时间】:2016-02-24 04:39:27
【问题描述】:

使用Fragments 与使用在不同布局中重复使用的自定义Views 相比有什么优势?

original blog post introducing fragments,Dianne Hackborn 说

[Fragments] 让开发人员更容易编写可扩展的应用程序 跨越各种屏幕尺寸,超越现有设施 在平台上可用。

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

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

Fragment 生命周期是:

onAttach(), onCreate(), onCreateView(), onActivityCreated(), onStart(), onResume(), onPause(), onStop(), onDestroyView(), onDestroy(), onDestroy(). >

View 生命周期是:

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

我想听听有编写大型应用程序经验的开发人员介绍他们在使用 Fragment 与自定义 View 将 UI 划分为可重用的部分时看到了哪些好处(如果有的话)。

【问题讨论】:

    标签: android android-fragments


    【解决方案1】:

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

    有时,您无法仅依靠视图来创建完全封装的 UI 组件。这是因为有些东西你想放入你的视图但不能,因为只有 Activity 可以处理它们,从而迫使 Activity 和视图之间紧密耦合。

    这是一个这样的例子。假设您想要创建一个可重用的 UI 组件,其中包括想要捕捉照片并用它做一些事情。传统上,您会触发一个启动相机并返回捕获的图像的意图。

    请注意,您的自定义 UI 组件无法完全封装此功能,因为它必须依赖托管 Activity 的 startActivityForResult,因为视图不接受 Activity 结果(它们可以通过上下文间接触发 Intent )。

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

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

    同样,您的片段可以为您的选项菜单添加项目,传统上只有 Activity 才能做到这一点。如果您的自定义视图的状态决定了菜单中的内容,这可能很重要。

    【讨论】:

    • 很好的答案,在我找到你的之前,我必须浏览 3-4 个类似的 SO 帖子。
    • “同样,您的片段可以为您的选项菜单提供项目,”@numan 如果您稍微解释一下这将是很大的帮助\
    【解决方案2】:

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

    可以将其视为一项小型活动,但您可以在屏幕上显示多个活动并与它们一起工作,包括在它们可见时相互交流。

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

    我已经将一个大型商业应用(>15 个活动)从活动重构为片段,以获得良好的平板电脑支持,我绝不会在没有片段的情况下启动新应用。

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

    【讨论】:

    • 但是我也可以使用自定义视图来实现你刚刚给出的那个例子。您可以让视图相互通信,并检查操作系统是否正在使用平板电脑或手机布局。我看到人们用碎片做同样的事情。用片段而不是视图来实现它有什么好处?
    • 也许片段为过渡、动画提供了更多支持,并且对于 ViewPager、ActionBar 和 Tabs 等某些容器来说是必需的。
    • @VIBrunazo 请参阅下面的答案。 stackoverflow.com/a/14912608/909956
    【解决方案3】:

    一些描述:

    把 Activity 想象成一个盛着一个大蛋糕的盘子。 Fragment 是一个将同一个蛋糕切成小块的容器。 每个切片都包含它自己的逻辑(侦听器等)。 总的来说,它们与一个大蛋糕几乎没有什么不同。

    好处:

    1. 当你盘子不能容纳一个大蛋糕。 (屏幕很小)您可以轻松地使用几个盘子(活动)来容纳每个盘子,而无需将您的逻辑移动到新活动中。

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

    3. 从某种意义上说,这是一种在 Android 编程中组织 UI 逻辑的更面向对象的方式。当你有一个特性(例如屏幕上的一个新分区)时,你创建一个新的 Fragment 类,对现有的活动类进行少量修改。但是,如果您只使用活动进行编程,则需要添加逻辑并对测试类进行较大的修改。

    只有我的 2 美分。 :)

    【讨论】:

    • 但是您可以轻松地将逻辑封装在您制作的每一片蛋糕中,而无需使用片段。我可以制作一个非常干净的 Activity,它只有一两行代码来创建和实例化小菜一碟。所有逻辑都在 cakes 类中
    • 那么总而言之,片段只是一种将 xml 与相关的 java 源代码耦合 并将它们放在一个独立于外部世界的包中的方法吗?我的意思是除此之外,如果我们可以想象一个图形也是从源代码创建的,我们可以使用常规类。 顺便说一句,在 Scala 中,有一个非常好的方法可以通过使用特征来解决这些问题!
    • 问题实际上是关于 Fragment 与 View,而不是 Fragment 与活动。
    • 确实是这样。片段与视图。而在 2016 年之后,我几乎不会相信碎片是不可替代的
    【解决方案4】:

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

    在某些方面,您可以将 Fragment 视为迷你 Activity

    与软件设计/开发中的许多事情一样,做事情的方法有很多种。您可以在许多不同的地方放置您的代码。是的,您可能可以在视图中投入很多内容,但是将不同的关注点放在不同的类中是一件好事。这方面的经典模式是 MVC,它适用于这种情况。您不想在视图中加入太多控制器逻辑。最好将它保存在类似控制器的类中,这些类是活动,现在是片段。这就是为什么 Fragment 的生命周期更像是 Activity 而不是视图的生命周期——它是为了促进这种组织。

    【讨论】:

    • 在 MVC 中,Fragment 和 Activity 似乎都扮演着控制器的角色。为什么不使用 POJO 类作为拆分控制器而不是 Fragments 的一种方式?
    【解决方案5】:

    我曾经接触过 Fragments,发现它们不是很有用(参见 this post)。根据我的阅读,片段实际上是一个可以访问活动上下文的对象的花哨词。我喜欢在我的工作中忽略片段,而自己创建这些对象。通过将Activity 传递给构造函数,而不是Context,我创建了非常大、要求非常高的应用程序。然而,使用 Fragments 的一个主要好处是 View 布局系统支持它们 - 因此您可以轻松地将它们添加到 Android xml(如果您将其用于布局)。

    【讨论】:

      【解决方案6】:

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

      使用 Fragments 还可以让您将组件分离到它们自己的类(Fragments)中,而不是在单个 Activity 中包含过多的逻辑。让我举个例子:

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

      如果您要尝试使用 Activity/自定义视图进行此操作,则您的整体 Activity 中的两个片段都有逻辑,您必须编写自定义视图,并且必须调试这个笨重的怪物.

      通常,片段是编写应用程序的一种更复杂、更强大的方式。他们可以做 Activity 可以做的所有事情,甚至更多。如果您不需要额外的功能,默认设置可能会让您到达您需要去的地方,并且工作量更少。

      【讨论】:

      • 就单体活动而言,为什么要使用片段而不是简单地将控制器代码拆分为其他 POJO 控制器类?
      • 这适用于片段中包含的逻辑(您可能应该对活动和片段都执行此操作),但您仍然会遇到将单个方法调用作为入口点的问题对于(至少)两个控制流,最好分离出来。您只能在一个地方覆盖 Android 用来与您的类进行通信的方法调用,因此,如果您有一个单一的活动,那么您有一个 OnCreateDialog() 为两组对话框调用,每个“屏幕”都调用一个。
      • 我还应该补充一点,使用 Fragment 代替 Activity 几乎没有任何缺点。很可能不需要编写任何额外的代码来获得与带有 Fragment 的 Activity 相同的行为,并且如果需要,您可以做更多的事情
      • @avh 在下面看到我的回答:stackoverflow.com/a/14912608/90995
      猜你喜欢
      • 1970-01-01
      • 2018-06-10
      • 2013-09-18
      • 2012-09-12
      • 1970-01-01
      • 2015-09-08
      • 2019-05-01
      • 2013-10-04
      • 2013-12-18
      相关资源
      最近更新 更多