困境:何时使用片段vs活动:

我知道Activities被devise成代表我的应用程序的一个屏幕,而Fragments被devise成可重复使用的UI布局,其中embedded了逻辑。

直到不久以前,我开发了一个应用程序,因为它说应该开发。 我创build了一个Activity来表示我的应用程序的屏幕,并使用ViewPagerGoogle Maps Fragments。 我很less创build一个可重复使用多次的ListFragment或其他UI。

最近我偶然发现一个只包含2个Activities的项目,一个是SettingsActivity ,另一个是MainActivityMainActivity的布局填充了许多隐藏的全屏UI片段,只显示一个。 在Acitivty逻辑中,应用程序的不同屏幕之间有许多FragmentTransitions

我喜欢这种方法是因为应用程序使用了一个ActionBar ,它保持不变,不会随着屏幕切换animation而移动,这是在Activity切换时发生的。 这给这些屏幕过渡更stream畅的感觉。

所以我想我所要求的是分享你关于这个话题的当前发展方式,我知道它可能看起来像一个基于意见的问题,但我把它看作是一个Androiddevise和体系结构问题…不是真的意见为主。

UPDATE(01.05.2014):SquareEric Burke之后(我不得不说是一个很棒的演示文稿,里面有很多android开发者的有用工具,而且我也没有任何关于Square的介绍)

http://www.infoq.com/presentations/Android-Design/

根据我过去几个月的个人经验,我发现构build我的应用程序的最佳方法是创build代表应用程序中stream的片段组,并将所有这些片段呈现在一个Activity 。 所以基本上,您的应用程序中的Activities数量与stream量数量相同。 这样一来,操作栏在所有stream程的屏幕上都保持完好,但正在通过改变stream程来重新创build,这是非常有意义的。 正如埃里克·伯克(Eric Burke)所说的那样,我也意识到,尽可能less地使用Activities的理念并不适用于所有的情况,因为它在他所谓的“上帝”活动中造成了混乱。

专家会告诉你:“当我看到用户界面时,我会知道是否使用ActivityFragment ”。 一开始这没有任何意义,但是到时候,你实际上可以告诉你是否需要Fragment

有一个很好的做法,我发现对我很有帮助。 当我试图向我的女儿解释一些事情的时候,我想起了这件事。

也就是说,想象一个代表屏幕的盒子。 你可以加载另一个屏幕在这个盒子? 如果你使用一个新的盒子,你将不得不从第一个盒子复制多个项目? 如果答案是肯定的,那么你应该使用Fragments ,因为根Activity可以容纳所有重复的元素,以节省你创build它们的时间,你可以简单地replace部分框。

但是不要忘记 ,你总是需要一个盒子容器( Activity ),否则你的零件将被分散。 所以一个箱子里面有零件

注意不要误用盒子。 Android的UX专家build议(你可以在YouTube上find它们),当我们应该明确加载另一个Activity ,而不是使用Fragment (就像我们处理导航抽屉里有类别)。 一旦你对Fragments感到满意,你可以观看他们所有的video。 更是他们的强制性材料。

你现在可以看看你的用户界面,并找出是否需要一个ActivityFragment ? 你有新的观点吗? 我想你是。

我的理念是这样的:

只有在绝对需要的情况下才能创build活动。 随着后台堆栈可用于提交大量的片段事务,我尝试尽可能在应用程序中创build尽可能less的活动。 而且,各种片段之间的通信要容易得多,而不是在活动之间来回发送数据。

活动转换很昂贵,对吗? 至less我相信 – 既然旧的活动被摧毁/暂停/停止,推到堆栈上,然后新的活动必须被创build/开始/恢复。

这是我的哲学,因为片段被引入。

那么,根据Google的讲座(也许在这里 ,我不记得了),只要有可能,就应该考虑使用Fragments,因为它使得代码更容易维护和控制。

但是,我认为在某些情况下,它可能会变得太复杂,因为承载片段的活动需要在它们之间进行导航/通信。

我想你应该自己决定什么是最适合你的。 把一个活动转换成一个片段通常并不难,反之亦然。

我已经在这里创build了一个关于这个dillema的post,如果你想进一步阅读。

为什么我喜欢所有情况下的片段比活动?

  • 活动是昂贵的。 在片段中,视图和属性状态是分开的 – 每当片段在backstack ,其视图将被破坏。 所以你可以堆叠更多的碎片比活动。

  • Backstack操纵。 使用FragmentManager ,很容易清除所有的碎片,比片段等插入更多。 但对于活动来说,操纵这些东西将是一场噩梦。

  • 一个可预测的生命周期 。 只要主机活动不回收。 在后台的碎片将不会被回收。 所以可以使用FragmentManager::getFragments()来查找特定的片段(不鼓励)。

除了你意识到的还有更多,你必须记住,发起的活动不会隐含地破坏调用活动。 当然,你可以设置它,让你的用户点击一个button进入一个页面,你开始该页面的活动,并摧毁当前的一个。 这会导致很多开销。 我能给你的最好的指导是:

**只有在主要活动和同一时间打开主要活动(想到多个窗口)的情况下开始新的活动。

有一个很好的例子,说明有多个活动是有道理的。 主要活动提供了一个文件浏览器。 当文件被打开时,启动一个新的活动来查看该文件。 您可以按最近的应用程序button,这将允许您返回浏览器而不closures打开的文档,然后甚至可以打开另一个文档与第一个文档并行。

在我看来,这并不重要。 要考虑的关键因素是

  1. 你多久会重用UI的一部分(例如菜单),
  2. 该应用程序也适用于平板电脑?

片段的主要用途是构build多面板活动,这使得它适用于平板电脑/手机响应应用程序。

不要忘记,一个活动是应用程序的块/组件,可以通过意图共享和启动! 所以你的应用程序中的每个活动只能解决一种任务。 如果你的应用程序只有一个任务,那么我认为你只需要一个活动和许多片段。 当然,你可以在未来的活动中重复使用片段来解决其他任务。 这种做法将任务明确和逻辑分离。 而且您不需要针对不同的片段组维护一个具有不同意图filter参数的活动。 您可以根据需求在开发过程的devise阶段定义任务。

事情我做了:尽可能less使用片段。 不幸的是,这几乎是可能的。 所以,我最终得到了很多碎片和一些活动。 我已经意识到一些缺点:

  • ActionBar &菜单:当2片段有不同的标题,菜单,那
    将难以处理。 例如:添加新的片段时,可以更改操作栏的标题,但是当从backstackpopup时,无法恢复旧的标题。 你可能需要一个工具栏在这个案例的每一个片段,但让我相信,这将花更多的时间。
  • 当我们需要startForResult ,activity有但是fragment没有。
  • 没有默认的转换animation

我的解决scheme是使用一个活动来包装一个片段。 所以我们有单独的操作栏,菜单, startActivityForResult ,animation,…

fragment重叠活动的一大优点是,用于片段的代码可以用于不同的活动,从而在应用程序开发中提供了代码的可重用性

我使用Fragments来获得更好的用户体验。 例如,如果你有一个Button,当你点击它时,你想运行一个web服务,我把一个Fragment附加到父Activity上。

 if (id == R.id.forecast) { ForecastFragment forecastFragment = new ForecastFragment(); FragmentManager fm = getSupportFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); ft.replace(R.id.main_content, forecastFragment); ft.addToBackStack("backstack"); forecastFragment.setArguments(b); ft.commit(); } 

用这种方式,用户不必在另一个活动中移动。

其次,我更喜欢片段,因为在旋转过程中可以轻松处理它们。

这取决于你想要build立真正的。 例如, navigation drawer使用碎片。 选项卡也使用fragments 。 另一个好的实现是你有一个listview 。 当您旋转手机并单击一行时,活动显示在屏幕的剩余一半。 我个人使用fragmentsfragment dialogs ,因为它更专业。 另外他们处理更容易旋转。

每个应用程序使用一个活动为fragment使用fragment提供基础,与activites片段相比,片段是activites片段可重复使用的片段更适合支持手机和平板电脑的应用程序

你可以自由使用其中之一。
基本上,你必须评估哪个是最适合你的应用的。 考虑如何pipe理业务stream程以及如何存储/pipe理数据首选项。

想一想,Fragments如何存储垃圾数据。 当你实现这个片段时,你有一个活动根目录来填充片段。 所以,如果你试图用太多的碎片来实现大量的活动,你必须考虑你的应用程序的性能,因为你正在操纵(粗略地讲)两个上下文生命周期,记住复杂性。

记住:我应该使用碎片吗? 为什么我不应该?

问候。