首页 文章

困境:何时使用碎片与活动:

提问于
浏览
700

我知道 Activities 被设计为代表我的应用程序的单个屏幕,而 Fragments 被设计为可重复使用的UI布局,其中嵌入了逻辑 .

直到不久前,我开发了一个应用程序,因为它说应该开发它们 . 我创建了一个 Activity 代表我的应用程序的屏幕,并使用了碎片 ViewPagerGoogle Maps . 我很少创建 ListFragment 或其他可以多次重复使用的UI .

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

我喜欢这种方法的原因是因为应用程序使用 ActionBar ,它保持不变并且不随屏幕切换动画移动,这就是 Activity 切换所发生的情况 . 这为这些屏幕转换提供了更流畅的感觉 .

所以我想我要问的是分享你关于这个主题的当前开发方式,我知道它看起来可能看起来像一个基于意见的问题,但我把它视为一个Android设计和架构问题...不是真的意见为基础的 .

UPDATE (01.05.2014):Eric Burke 之后 Eric Burke 进行了这次演示,(我不得不说这是一个很棒的演示文稿,为Android开发人员提供了许多有用的工具 . 而且我与Square没有任何关系)

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

根据我过去几个月的个人经验,我发现构建应用程序的最佳方法是创建在应用程序中代表 flow 的片段组,并将所有这些片段显示在一个 Activity 中 . 所以基本上你的应用程序中的 Activities 数与流的数量相同 . 这样,动作栏在所有流程的屏幕上保持完整,但正在重新创建流程,这很有意义 . 正如埃里克伯克所说,并且我也已经意识到,尽可能少地使用 Activities 的哲学并不适用于所有情况,因为它在他所谓的"God"活动中造成混乱 .

13 回答

  • 54

    在我看来,这并不是真的相关 . 要考虑的关键因素是

    • 您多久会重复使用部分UI(例如菜单),

    • 也适用于平板电脑?

    片段的主要用途是构建多窗格活动,这使其成为平板电脑/手机响应式应用的理想选择 .

  • 2

    好吧,根据谷歌的讲座(也许here,我可能不会这样做,因为它使您的代码更容易维护和控制 .

    但是,我认为在某些情况下它会变得太复杂,因为托管片段的活动需要在它们之间导航/通信 .

    我想你应该自己决定什么对你最好 . 将活动转换为片段通常并不难,反之亦然 .

    我已经创建了一篇关于这个dillema here的帖子,如果你想进一步阅读的话 .

  • 110

    您可以自由使用其中之一 .
    基本上,您必须评估哪个是您的应用程序中最好的一个 . 考虑如何管理业务流以及如何存储/管理数据首选项 .

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

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

    问候 .

  • 8

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

    有一个很好的做法,我发现对我很有帮助 . 当我试图向女儿解释一些事情时,我突然想到了 .

    即,想象一个表示屏幕的框 . 你能在这个盒子里加载另一个屏幕吗?如果您使用新的盒子,是否需要从第一个盒子中复制多个项目?如果答案是肯定的,那么你应该使用 Fragments ,因为根 Activity 可以容纳所有重复的元素以节省你创建它们的时间,你可以简单地替换盒子的部分 .

    don't forget 你总是需要一个盒子容器( Activity )或你的零件将被分散 . 所以一个盒子里面有零件 .

    小心不要误用盒子 . Android UX专家建议(你可以在YouTube上找到它们)我们应该明确加载另一个 Activity ,而不是使用 Fragment (就像我们处理具有类别的导航抽屉时) . 一旦您对 Fragments 感到满意,您就可以观看他们的所有视频 . 更多是强制性材料 .

    你现在可以看看你的用户界面并找出答案如果你需要 ActivityFragment ?你有新观点吗?我想你做到了 .

  • 8

    这取决于你想要真正 Build 什么 . 例如, navigation drawer 使用片段 . 标签也使用 fragments . 另一个很好的实现,就是你有一个 listview . 旋转手机并单击一行时,活动将显示在屏幕的剩余一半中 . 就个人而言,我使用 fragmentsfragment dialogs ,因为它更专业 . 另外,它们在旋转时更容易处理 .

  • 1

    为什么我喜欢片段而不是所有情况下的活动 .

    • 活动很贵 . 在Fragment中,视图和属性状态是分开的 - 只要片段在_159019中,它的视图就会被销毁 . 所以你可以堆积比活动更多的碎片 .

    • Backstack 操纵 . 使用 FragmentManager ,可以轻松清除所有碎片,插入多个碎片等 . 但对于Activity来说,操纵这些东西将是一场噩梦 .

    • 一个可预测的生命周期 . 只要主机Activity不被回收 . 背板中的碎片不会被回收 . 因此可以使用 FragmentManager::getFragments() 来查找特定的片段(不鼓励) .

  • 22

    除此之外,还有更多内容,您必须记住,启动的活动不会隐式破坏调用活动 . 当然,您可以进行设置,以便用户单击按钮转到页面,启动该页面的活动并销毁当前页面 . 这会导致很多开销 . 我能给你的最佳指南是:

    **只有在主要活动和同一个活动同时打开时才开始新的活动(想想多个窗口) .

    Google Cloud 端硬盘是一个很好的例子,说明何时进行多项活动是有意义的 . 主要活动提供了一个文件浏览器 . 打开文件时,将启动一个新活动以查看该文件 . 您可以按最近的应用程序按钮,这将允许您返回浏览器而不关闭打开的文档,然后甚至可能打开与第一个文档并行的另一个文档 .

  • 12

    不要忘记一个活动是应用程序的块/组件,可以通过Intent共享和启动!因此,应用程序中的每个活动都应该只解决一种任务 . 如果您的应用程序中只有一个任务,那么我认为您只需要一个活动和许多片段 . 当然,您可以在未来的活动中重用碎片来解决其他任务 . 这种方法将明确和逻辑分离任务 . 并且您无需为不同的片段集维护具有不同intent过滤器参数的一个活动 . 您可以根据需求在开发过程的设计阶段定义任务 .

  • 7

    我做了:尽可能使用更少的片段 . 不幸的是,几乎可以 . 所以,我最终得到了很多片段和一些活动 . 我意识到的一些缺点:

    • ActionBar &菜单:当2个片段有不同的 Headers ,菜单时,那个
      很难处理 . 例如:添加新片段时,您可以更改操作栏 Headers ,但是当从 backstack 弹出时,无法恢复旧 Headers . 在这种情况下,您可能需要在每个片段中使用工具栏,但请相信我,这将花费您更多时间 .

    • 当我们需要 startForResult 时,活动有,但片段没有 .

    • 默认情况下没有过渡动画

    我的解决方案是使用Activity将片段包装在里面 . 所以我们有单独的动作栏,菜单, startActivityForResult ,动画,......

  • 3

    我的理念是这样的:

    只有在绝对绝对需要时才创建活动 . 随着backstack可用于提交一堆片段事务,我尝试尽可能少地在我的应用程序中创建活动 . 此外,各种片段之间的通信更容易,而不是在活动之间来回发送数据 .

    活动转换很昂贵,对吧?至少我是这么认为的 - 因为旧活动被销毁/暂停/停止,被推入堆栈然后必须创建/启动/恢复新活动 .

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

  • 1

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

  • 1

    fragment over活动的一大优点是,用于片段的代码可以用于不同的活动 . 因此,它提供了应用程序开发中代码的可重用性 .

  • 238

    我使用Fragments来获得更好的用户体验 . 例如,如果您有一个Button并且想要运行,请在单击它时说一个webservice,我将一个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();
    }
    

    以这种方式,用户将不必移动另一个活动 .

    其次我更喜欢Fragments,因为你可以在旋转过程中轻松处理它们 .

相关问题