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

时间:2011-12-23 15:25:57

标签: android android-fragments android-view android-lifecycle software-design

在为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

这两种方法都非常简单,可以在一个Activity中使用,例如,要显示List<Foo>(例如,以编程方式将每个方法添加到ScrollView),所以{{{ 1}}真的有用,或者它们只是一个过于美化的简化获取视图,例如通过上面的代码?

6 个答案:

答案 0 :(得分:165)

使用Fragments的主要原因是针对Backstack和生命周期功能。否则,自定义视图更轻,更容易实现。

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

我在回答之后意识到我在一年前发布了类似的问题: https://stackoverflow.com/a/11126397/618881

答案 1 :(得分:27)

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

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

我认为没有任何理由为每个View使用Fragments,我想这只是一个开销。我只在第一个用例中使用它们,我在这里说这是一个简化。

答案 2 :(得分:3)

  

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

Here你可以阅读更多内容。

答案 3 :(得分:3)

  1. 场景活动拆分屏幕 - 我们有一个布局和一个处理左右屏幕部分的活动
  2. 场景FragmentActivity我们有一个主屏幕布局,一个用于左侧一个用于右侧
  3. 如果你有简单的应用程序,情况一是好的。

    如果您想拥有多个碎片和多个FragmentActivities,则场景二很好 你可以把每一个结合起来。您也可以在片段之间进行交互。

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

    但它会让你的项目更大。但如果你做大项目,你可以节省很多。因为您可以使用相同的片段或相同的片段活动。

    而且我觉得这些碎片来得太迟了所以你必须尝试以新的方式思考。 也许只是尝试将您的活动转换为FragmentActivity。稍后尝试找到可重复使用的代码并从中创建Fragment。

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

    这总是有问题的。 Android团队做了一些思考,没有人知道什么是好事。因为我们很难像现在这样学习,而且这里有一些新东西。

    在我看来,谷歌告诉我们这是好的,但不是理由。

答案 4 :(得分:0)

在CustomView上使用Fragment或Activity时添加一个案例:

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

答案 5 :(得分:-2)

上述评论中没有提到的一件大事是,即使Android杀死了活动,片段仍会驻留在内存中,当您执行更改设备方向等操作时,会重新启动它。这是出于性能原因而完成的,但如果您希望销毁片段只是为了发现它们无法重新创建,那么也会导致意外结果。