在 Android 中使用 Fragments 而不是 Views 有啥好处?

Posted

技术标签:

【中文标题】在 Android 中使用 Fragments 而不是 Views 有啥好处?【英文标题】:What is the benefit of using Fragments in Android, rather than Views?在 Android 中使用 Fragments 而不是 Views 有什么好处? 【发布时间】:2012-01-26 21:50:57 【问题描述】:

在为android 开发时,您可以将目标(或最小)sdk 设置为 4 (API 1.6) 并添加 android 兼容包 (v4) 以添加对Fragments 的支持。昨天我这样做并成功实现了Fragments 来可视化来自自定义类的数据。

我的问题是:使用Fragments 与简单地从自定义对象获取视图并仍然支持 API 1.5 相比有什么好处?

例如,假设我有 Foo.java 类:

public class Foo extends Fragment 

    /** Title of the Foo object*/
    private String title;
    /** A description of Foo */
    private String message;

    /** Create a new Foo
     * @param title
     * @param message */
    public Foo(String title, String message) 
        this.title = title;
        this.message = message;
    //Foo

    /** Retrieves the View to display (supports API 1.5. To use,
     * remove 'extends Fragment' from the class statement, along with
     * the method @link #onCreateView(LayoutInflater, ViewGroup, Bundle)) 
     * @param context Used for retrieving the inflater */
    public View getView(Context context) 
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View v = inflater.inflate(R.layout.foo, null);
        TextView t = (TextView) v.findViewById(R.id.title);
        t.setText(this.title);
        TextView m = (TextView) v.findViewById(R.id.message);
        m.setText(this.message);
        return v;
    //getView 

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
        if (container == null) 
            return null;
        
        View v = inflater.inflate(R.layout.foo, null);
        TextView t = (TextView) v.findViewById(R.id.title);
        t.setText(this.title);
        TextView m = (TextView) v.findViewById(R.id.message);
        m.setText(this.message);
        return v;
    //onCreateView

//Foo

这两种方法的创建和使用都很简单有用,或者它们只是通过上面的代码获得视图的过度美化简化?

【问题讨论】:

片段不一定要有 UI,它们可以是可重用的行为。在这种情况下,视图将是多余的。 我已经在另一个问题中回答了这个问题。请参阅***.com/a/14912608/909956T;dr - 有时片段允许您创建比依赖自定义视图实现更多的可重用组件。查看链接了解原因。 【参考方案1】:

使用 Fragments 的主要原因是为了回栈和生命周期特性。否则,自定义视图会更轻量级且更易于实现。

起初,我实际上尝试使用自定义视图构建手机/平板电脑应用程序。一切似乎都可以在手机和平​​板电脑上使用,甚至可以从单面板切换到拆分面板。我遇到麻烦的地方是后退按钮和生命周期。因为我只是手动更新视图......没有任何东西可以跟踪视图的历史及其状态。因此,后退按钮没有按预期工作,即使在生命周期事件期间(例如旋转应用程序时)也很难重新创建最新状态。为了解决这个问题,我必须将自定义视图包装在片段中并使用 FragmentManager 以便保存和重新创建之前的状态。

在回答一年前我发布过一个类似的问题后,我意识到: https://***.com/a/11126397/618881

【讨论】:

很好的答案。我只是想补充一点,从 4.2 开始可以嵌套片段或支持库 rev 11。 感谢@Karlo 的更新。我认为这在概念上是不可能的,但他们通过 getChildFragmentManager() 使用私有 FragmentManager 来解决它。哦,它是 API 17,而不是 11,可通过支持库获得。 我刚刚又在看这个问题,我的经历也发生了变化。这是一个很好地理解优点和缺点的答案,并且非常有帮助。谢谢! 想要 +1 这个答案,但这样做会破坏当前分数。此外,70 不是我最喜欢的数字。 去年,我还认为Fragments没有提供任何额外的普通功能,但我体验到在点击活动后我失去了所有下载的图像,所以不得不添加缓存实现,现在我在考虑使用片段可能很容易【参考方案2】:

我想说片段在两种情况下很有用:如果您在某些设备/方向上拆分视图并在两个活动中显示它们,并在其他设备上显示所有内容。如果您使用平板电脑或什至在手机上以横向模式使用,这将是一个用例:例如您在一个屏幕上显示项目列表和详细信息。在手机或纵向模式下,您只显示一个部分。

另一个用例是可重用视图。因此,如果您有一些在不同活动上可见的视图并且还执行一些操作,您可以将此行为放入片段中,然后重用它。显然,您也可以使用自定义小部件来做到这一点。

我看不出有任何理由为每个视图使用 Fragments,我想这只是开销。我只在第一个用例中使用它们,我想说这是一种简化。

【讨论】:

谢谢,这绝对有帮助。我想我会坚持使用视图并制作自己的“后台堆栈”以使其可重用。【参考方案3】:

Android 在 Android 3.0(API 级别 11)中引入了 Fragment,主要是为了支持大屏幕(例如平板电脑)上更加动态和灵活的 UI 设计。因为平板电脑的屏幕比手机大得多,所以有更多的空间来组合和交换 UI 组件。片段允许这样的设计,而无需您管理对视图层次结构的复杂更改。通过将 Activity 的布局划分为片段,您可以在运行时修改 Activity 的外观,并将这些更改保存在由 Activity 管理的后退堆栈中。

Here你可以阅读更多。

【讨论】:

我已经阅读了所有文档,但是我一直在寻找能够更好地解释它们的好处的东西,例如平板电脑或 backstack【参考方案4】:
    场景活动分屏 - 我们有一个布局和一个处理左右屏幕部分的活动 Scenario FragmentActivity 我们有一种布局用于主屏幕,一种用于左侧,一种用于右侧

如果您有简单的应用程序,场景一很好。

如果你想拥有多个 Fragment 和多个 FragmentActivity,场景二很好 你可以结合每一个。您还可以在片段之间进行交互。

我有分屏 Fragmentactivity,我可以用“Intent Extras”调用它,并告诉 fragmentActivity 要加载哪个片段。片段很好,因为它们不在清单中,因此您可以制作可重用的片段和 FragmentActvity。

但这会使您的项目更大。但是,如果您制作大型项目,则可以节省很多。因为您可以使用相同的 Fragment 或相同的 Fragment 活动。

而且我认为这些片段来得有点晚,所以你必须尝试以新的方式思考。 也许只是尝试将您的活动转换为 FragmentActivity。稍后尝试找到可重用的代码并从中制作 Fragment。

它很有用,但我现在不知道如何。但我有一些想法。

这总是问题。 Android 团队做了一些思考,没有人知道什么是好的。因为我们几乎没有像以前那样学习,所以它出现了一些新事物。

在我看来这很好,但不是因为谷歌告诉我们的原因。

【讨论】:

【参考方案5】:

在 CustomView 上使用 Fragment 或 Activity 时添加一种情况:

当您使用 CursorLoader 观察某些视图、ListView 或 TextView 并希望在后端的 ContentProvider 数据更新时更新它们的显示值(最常见的情况是,您有一项服务通过轮询远程数据库的数据来更新本地数据库/cloud 定期)

【讨论】:

【参考方案6】:

上述所有 cmets 都没有提到的一件大事是,即使 Android 在您执行更改设备方向之类的操作时终止 Activity 并重新启动它,片段仍然驻留在内存中。这样做是出于性能原因,但如果您希望片段被销毁,却发现它们不知从何处重新创建,也可能导致意外结果。

【讨论】:

以上是关于在 Android 中使用 Fragments 而不是 Views 有啥好处?的主要内容,如果未能解决你的问题,请参考以下文章

Fragments 中的成员变量与 setArguments

使用 Fragments 进行 Android 搜索

在 Fragments 中使用 JSON 时,应用在 Android 开发中没有响应

在Android中使用ActivityGroup或Fragments等正确管理导航?

以有效的方式管理android片段创建?

Android Navigation Drawer Show Up Indicator for Lower Level Fragments