有多少活动与片段?


185

介绍:

基本的“片段教程”模式如下所示:

  1. 在平板电脑上,左侧有一个列表,右侧有详细信息。
  2. 两者都是 Fragments并且都居住在同一个Activity
  3. 在电话上,将一个清单Fragment合二为一Activity
  4. 启动Activity包含详细信息的新文件Fragment

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

在这两个设备,功能是在Fragments。(简单)

平板电脑上,整个应用程序是1Activity,在手机上,有很多Activities


问题:

  • 是否有理由将手机应用拆分为多个Activities

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

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

这样,大多数逻辑都驻留在Fragments自身中,并且只有一个Activity-较少的代码重复。

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

教程是否过于简化,还是我错过了这种方法的主要知识?


我们已经在办公室成功地尝试了这两种方法-但我将要开始一个更大的项目,并希望尽可能简化自己的工作。

一些与相关问题有关的链接:


更新

开始悬赏的问题-仍然不确定为什么我需要在平板电脑活动和每个电话活动中重复应用逻辑。

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


38
+1是一个很棒且写得很好的问题。
Siddharth Lele 2012年

这让我今天很痛苦,目前,我正在开发一个应用程序,该应用程序的设计包含很多片段,并且可以在手机和平​​板电脑上使用,我正在寻找一种中间方法,但找不到任何方法...
Nixit Patel 2012年

1
老实说,我没有冒犯的意思,但我认为您只是接受了您想听的内容,而不是真正的答案。Google不推荐Scuba的答案,我喜欢在博客中解释原因。
pjco 2012年

1
@pjco具体来说,我不同意onItemSelected()Activity 中的方法。在我的“真实”应用中,我有很多列表和子列表。此模式表明我的Tab活动必须具有一种onItemSelected()处理每个列表的方法。另外,电话活动中的每个活动必须具有相同的逻辑。恕我直言,最好将“选定项”逻辑放入每个片段中-无需重复,我更喜欢这种构造代码的方式。我希望这对您有帮助
Richard Le Mesurier

2
我目前在工作中陷入这种困境。片段加载比推出新的活动速度较快,所以我就开始实行单一的活动架构。但是,我遇到了一个问题,那就是我似乎找不到不做任何改动就可以支持多片段配置的好方法。看到这个问题
theblang

Answers:


41

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

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


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

在此演示中,逻辑已从Activity和移出Fragment。该TitlesFragment实际上包含更改碎片的逻辑。这样,每个活动都非常简单。要复制许多非常简单的活动,而其中没有逻辑包含在活动中,则使其变得非常简单。

通过将逻辑放入“片段”中,无需多次编写代码。无论将片段放置在哪个活动中,它都是可用的。这比基本教程建议的模式更强大。

    /**
    * 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模式的另一个优点是,您不会最终遇到包含大量逻辑的“平板电脑活动”,这意味着您可以节省内存。教程模式可以导致更复杂的应用程序中发生大量的主要活动。因为它需要随时处理放置在其中的所有片段的逻辑。

总体而言,不要认为它被迫使用许多活动。可以将它想象成有机会将您的代码分成许多片段,并在使用它们时节省内存。


全面的答案-我看过ABS演示,我认为那里有很多不错的代码。我将尝试将我的大部分逻辑移到“片段”中
理查德·勒·梅苏里尔

演示应用已经搬到这里:play.google.com/store/apps/...
菲利普·E.

我认为您所描述的模式来自原始的Google示例代码:android-developers.blogspot.com/2011/02/… 我认为ActionBarSherlock刚刚移植了Google演示代码以使用ABS类。
Dan J

17

我认为您在正确的轨道上。(是的,这些教程过于简化了)。

在数位板布局中,您可以使用一个“活动”并在多个“窗格”中切入和切出片段。在电话布局中,您可以为每个片段使用新的活动。

像这样:

在此处输入图片说明

这似乎需要做很多额外的工作,但是通过在电话上使用多个活动,您可以启用基本的活动生命周期和Intent传递。这也允许框架处理所有动画和后向堆栈。

为了帮助减少代码,您可以使用BaseActivity和扩展代码。

因此,如果用户使用平板电脑,则可以使用平板电脑MyMultiPaneFragActivity或类似设备。此活动负责管理从片段的回调并将路由意图路由到正确的片段(例如搜索意图)

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

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

我认为这是推荐的方式,是为了节省内存并降低复杂性和耦合性。如果要换出Fragments,则FragmentManager维护会为后堆栈保留对该Fragment的引用。它还简化了用户应该“运行”的内容。此设置还将Fragment中的视图,布局和逻辑与Activity生命周期脱钩。这样,一个片段可以存在于单个活动中,与另一个片段(两窗格)或三窗格活动等并存。

*定期进行意图路由的好处之一是,您可以从后堆栈的任何位置显式启动活动。搜索结果就是一个例子。(MySearchResults.class)。

在这里阅读更多内容:

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

这可能是一些前期工作,因为每个片段必须在单独的活动中都能很好地工作,但是通常会有所收获。这意味着您可以使用其他布局文件来定义不同的片段组合,保持片段代码模块化,简化操作栏管理,并让系统处理所有后退堆栈工作。


重新发挥MySearchResults的优势-您建议根据手机或平板电脑采用不同的方式来响应该意图-为什么这比在两种情况下都具有一个单独的活动要好?您建议在Tablet上没有常规的意图路由-因此无论如何您都必须解决Tablet的问题。为什么不在手机上也使用该解决方案?
理查德·勒·马苏里尔

这样做的好处是您的平板电脑代码可以路由到多个窗格。有时,您可能想在一个意图上更改多个窗格。例如左侧的搜索结果,右侧较大窗格中的第一项详细信息。此代码无法移植到单个布局。
pjco 2012年

如果有很多片段,为什么可以切换片段,但是如果只有一个片段可见,那么我就不能切换到另一个片段?
理查德·勒·马修里尔

不确定我是否理解您的意思,但是在上面澄清我的评论:有时您可能想在多片段布局中同时更改多个片段。这需要代码来更改2个片段,您不会在单个片段布局中重复使用
pjco 2012

欢迎您:)如果您认为答案是有帮助的
投票

6

这里是雷托·梅尔的关于相同的答案,从拍摄这段视频Udacity的Android基础课程

有许多原因使您最好将应用程序分解为不同的活动。

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

一个好的经验法则是,只要上下文发生更改,就创建一个新的活动。例如,显示不同种类的数据并同时从查看切换为输入数据。


有趣的是,视频的标题是“为什么我们不只使用片段”
理查德·勒·梅苏里尔

这是一个很好的方法,它面临着大量的单一活动多个片段的问题……可能是真正的经验
GvSharma 2015年

4

这种方法的一个问题是,您在Tablet主活动和单独的电话活动中重复了很多逻辑。

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

您的细节逻辑应绑在细节片段中。因此,活动之间不存在与细节逻辑相关的代码重复-细节活动仅显示细节片段,可能会从Intent多余内容中传入数据。

另外,我对ActionBarSherlock的了解是,它似乎最适合Fragments而不是Activity(但我尚未使用它)。

由于ActionBarSherlock纯粹是本机操作栏的反向端口,因此ActionBarSherlock与片段无关,与本机操作栏无关。


您对单一活动的想法是什么?
theblang 2014年

@mattblang:只要您正确导航,就不会有问题。
CommonsWare 2014年

1
我尝试将其重构为单个活动架构,因为替换片段比启动包含相同片段的新活动要快得多。我觉得我遇到了太多的碰壁不过,像这样。我在网上找到的大多数示例,尤其是对于多片段配置(例如主从细节),都不使用单个活动。所以我有点两难。
theblang 2014年

0

提到第一个问题“是否有理由将手机应用分为多个活动?” -是的 它完全取决于可用空间,平板电脑为开发人员提供了更多空间,从而使开发人员可以在一个屏幕上放置更多内容。Android告诉我们Activity可以提供一个屏幕。因此,在平板电脑上使用1个大屏幕可以做的事情可能是必须分布在手机的多个屏幕上,因为没有足够的空间容纳所有碎片。


第一句话-“活动是一个应用程序组件,它提供一个屏幕,用户可以与之交互以执行某项操作”。我在原始声明中确实看到了一个错误,我不是要放“另一个屏幕”,
EFlisio
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.