188

介绍:

基本的“片段教程”模式是这样的:

  1. 在平板电脑上,左侧有列表,右侧有详细信息。
  2. 两者都是 Fragments并且都驻留在同一个Activity.
  3. 在手机上,将列表Fragment合二为一Activity
  4. 启动一个新Activity的细节Fragment

(例如Dianne Hackborn的 Android 3.0 Fragments API 和Fragments API Guide

在这两种设备上,功能都在Fragments. (简单的)

平板上,整个app是1Activity,在手机上,有很多Activities


问题:

  • 是否有理由将电话应用程序拆分为多个Activities

这种方法的一个问题是,您在主 Tablet和单独的 Phone 中复制了很多逻辑ActivityActivities

  • Fragments在这两种情况下保留 1 Activity 模型,使用相同的切换进出逻辑(只是使用不同的布局)会不会更容易?

这样,大部分逻辑都存在于Fragments它们自身中,并且只有一个Activity更少的代码重复。

另外,我所读到的ActionBarSherlock是,它似乎最适合使用Fragments而不是Activities(但我还没有使用它)。

教程是否过于简单,或者我错过了这种方法的主要内容?


我们已经在办公室成功地尝试了这两种方法——但我即将开始一个更大的项目,并且想让事情对自己来说尽可能简单。

一些相关问题的链接:


更新

在问题上开始赏金 - 仍然不相信为什么我需要在我的平板电脑活动和每个手机活动中复制我的应用程序逻辑。

还发现了 Square 的人写的一篇有趣的文章,非常值得一读:

4

5 回答 5

42

我同意教程非常简化。他们只是介绍Fragments,但我不同意建议的模式。

我也同意在许多活动中复制应用程序的逻辑不是一个好主意(请参阅维基百科上的 DRY 原则)。


ActionBarSherlock我更喜欢Fragments Demo 应用程序使用的模式(在此处下载源代码)。与问题中提到的教程最匹配的演示是应用程序中称为“布局”的演示;或FragmentLayoutSupport在源代码中。

Activity在此演示中,逻辑已从Fragment. 实际上包含更改片段的TitlesFragment逻辑。这样,每个Activity就很简单了。复制许多非常简单的活动,其中没有任何逻辑在活动内部,这使得它非常简单。

通过将逻辑放入 Fragments 中,无需多次编写代码;无论将 Fragment 放入哪个 Activity,它都可用。这使它成为比基本教程建议的模式更强大的模式。

    /**
    * Helper function to show the details of a selected item, either by
    * displaying a fragment in-place in the current UI, or starting a
    * whole new activity in which it is displayed.
    */
    void showDetails(int index)
    {
        mCurCheckPosition = index;

        if (mDualPane)
        {
            // We can display everything in-place with fragments, so update
            // the list to highlight the selected item and show the data.
            getListView().setItemChecked(index, true);

            // Check what fragment is currently shown, replace if needed.
            DetailsFragment details = (DetailsFragment) getFragmentManager()
                .findFragmentById(R.id.details);
            if (details == null || details.getShownIndex() != index)
            {
                // Make new fragment to show this selection.
                details = DetailsFragment.newInstance(index);

                // Execute a transaction, replacing any existing fragment
                // with this one inside the frame.
                FragmentTransaction ft = getFragmentManager()
                    .beginTransaction();
                ft.replace(R.id.details, details);
                ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
                ft.commit();
            }

        }
        else
        {
            // Otherwise we need to launch a new activity to display
            // the dialog fragment with selected text.
            Intent intent = new Intent();
            intent.setClass(getActivity(), DetailsActivity.class);
            intent.putExtra("index", index);
            startActivity(intent);
        }
    }

ABS模式的另一个优点是您最终不会得到包含大量逻辑的 Tablet Activity,这意味着您可以节省内存。教程模式可以在更复杂的应用程序中导致非常大的主要活动;因为它需要随时处理放置在其中的所有片段的逻辑。

总的来说,不要认为它是被迫使用许多活动。可以将其视为有机会将您的代码拆分为许多片段,并在使用它们时节省内存。

于 2012-09-21T10:06:46.277 回答
18

我认为你在正确的轨道上。(是的,教程过于简单)。

在平板电脑布局中,您可以使用单个活动并换入和换出片段(在多个“窗格”中)。在手机布局中,您可以为每个 Fragment 使用新的 Activity。

像这样:

在此处输入图像描述

这似乎是很多额外的工作,但通过为手机使用多个活动,您可以启用基本的活动生命周期和意图传递。这也允许框架处理所有动画和回栈。

为了帮助减少代码,您可以使用 aBaseActivity并从中扩展。

因此,如果用户有您会使用的平板电脑MyMultiPaneFragActivity或类似的东西。此活动负责管理来自片段的回调并将意图路由到正确的片段(例如搜索意图)

如果用户有电话,您可以使用很少的代码来使用常规活动,并对其进行扩展MyBaseSingleFragActivity或类似的东西。这些活动可能非常简单,5-10 行代码(甚至可能更少)。

棘手的部分是路由意图等等。*(编辑:见下文)。

我认为这是推荐方法的原因是节省内存并降低复杂性和耦合性。如果您要换出 Fragment,FragmentManager则为 back-stack 维护对该 Fragment 的引用。它还简化了应该为用户“运行”的内容。此设置还将 Fragment 中的视图、布局和逻辑与 Activity 生命周期分离。这样,Fragment 可以存在于单个 Activity 中,与另一个 Fragment 一起(两窗格)或三窗格 Activity 等。

*拥有常规意图路由的好处之一是您可以从后台堆栈中的任何位置显式启动 Activity。一个例子可能是搜索结果。(MySearchResults.class)。

在这里阅读更多信息:

http://android-developers.blogspot.com/2011/09/preparing-for-handsets.html

这可能需要更多的前期工作,因为每个片段必须在不同的活动中很好地工作,但通常会得到回报。这意味着您可以使用定义不同片段组合的替代布局文件,保持片段代码模块化,简化操作栏管理,并让系统处理所有回栈工作。

于 2012-09-11T07:14:11.080 回答
6

这是 Reto Meier 对此的回答,取自Udacity 的 Android 基础课程视频

有很多原因,你最好把你的应用分成不同的活动。

  • 拥有单一的单体活动会增加代码的复杂性,使其难以阅读、测试和维护。
  • 使创建和管理意图过滤器变得更加困难。
  • 增加了紧密耦合独立组件的风险。
  • 如果单个活动包括敏感信息和可以安全共享的信息,则更有可能引入安全风险。

一个好的经验法则是在上下文发生变化时创建一个新的活动。例如,显示不同类型的数据,同时从查看数据切换到输入数据。

于 2015-05-14T05:32:58.370 回答
4

这种方法的一个问题是,您在主 Tablet Activity 和单独的 Phone Activity 中复制了很多逻辑。

在主从模式中,有两个活动。一个在大屏幕上显示两个片段,在小屏幕上只显示“主”片段。另一个在较小的屏幕上显示“细节”片段。

您的详细逻辑应绑定在详细信息片段中。因此,活动之间不存在与细节逻辑相关的代码重复——细节活动仅显示细节片段,可能从Intent额外的数据中传递数据。

另外,我读到的关于 ActionBarSherlock 的内容是,它似乎最适合使用 Fragments 而不是活动(但我还没有使用它)。

ActionBarSherlock 与片段无关,与原生操作栏无关,因为 ActionBarSherlock 纯粹是原生操作栏的向后移植。

于 2012-09-24T12:30:42.423 回答
0

参考第一个问题“是否有理由将手机应用程序拆分为多个活动?” - 是的。它只是归结为可用空间,平板电脑为开发人员提供了更多空间,从而允许开发人员在一个屏幕上放置更多内容。Android 告诉我们,Activities 可以提供一个屏幕。因此,您可以在平板电脑上使用 1 个大屏幕做的事情,可能必须在手机上的多个屏幕上展开,因为没有足够的空间容纳所有片段。

于 2015-05-24T10:31:22.937 回答