『译文』向Big Nerd Ranch提问:为何Fragment在Android App开发中很是重要?

译者说:html

《Android权威编程指南 The Big Nerd Ranch Guide》是一本很是优秀的 android app 开发入门书籍,这本书经过几个或复杂或简单的 app 开发,按部就班(毫不是填鸭式)地引导初学者学习 androi app 开发的各类知识。而书中几乎全部应用的界面都是基于 fragment 来构建的。java

书中的第7~12章、16~22章完成了一个功能复杂的APP开发,能够学习到:android

  • 如何使用 Fragment 构建『列表-详情』界面;web

  • 如何使用 ViewPager 滑动屏幕以切换不一样的『详情』界面;数据库

  • 如何根据屏幕大小选择布局;编程

  • 如何在 fragment 间,以及在 activity 和 fragment 间传递数据;segmentfault

  • 其它知识点:操做栏、上下文菜单、隐式 intent、JSON、定制 ListViewItem、MVC;服务器

书中的第14章专门讲了如何在设备旋转时保存 Fragment 的交互状态。而设备旋转时须要处理的其它事情包括『设备旋转时保存Activity的交互状态』在3.二、3.3;『设备旋转时保存WebView的数据』在31.3;『设备旋转时保存在自定义View中绘制的图形』在32.5。网络

而这篇文章几乎能够看做是对上述全部内容的综述,做者试图告诉咱们为什 fragments 如此重要。若是你读过这本书,你能够把这篇文章看成总结;若是你没读过,能够看成概览。app

且听他讲。

原文出处, Aug 13, 2013,by Big Nerd Ranch.
译者:li21, weiyi.just2@gmail.com, 2015-12-04, 禁止转载


Ask Big Nerd Ranch: Why do Fragments Matter in Android Application Development?

Q: Why does your book Android Programming heavily advocate the use of fragments when developing Android applications? You can develop Android applications without using any fragments, so why bother? Why do fragments matter?

问:为何在你的书里极力倡导使用 Fragment 开发 Android App 呢?不使用 Fragment 也能够开发 App,为何要绕个弯子呢?为何认为 Fragment 如此重要?

A: As Android developers, we have two main controller classes available to us: Activities and Fragments.

Activities have been around for a very long time and are used to construct a single screen of your application. When someone is using your Android application, the views that the user sees and interacts with are hosted and controlled by a single activity. Much of your code lives in these Activity classes, and there will typically be one activity visible on the screen at a time.

As an example, a simple activity may look like the following:

答:做为 Android 开发者,可使用的两个主要的 controller classes 是 Activity 和 Fragment.

Activities 已经被用于构建单屏界面很长时间了。用户使用你的 App 时所看到的、与之交互的界面,是被某个 activity 托管和控制的。大部分代码存在于这些 Activity 类内,某个时刻一般会有一个 activity 处于可见状态。

举个栗子,一个简单的 activity 看起来像这样:

public class MainActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

When Honeycomb was released, the Fragment class was introduced. Fragments are another type of controller class that allows us to separate components of our applications into reusable pieces. Fragments must be hosted by an activity and an activity can host one or more fragments at a time.

A simple fragment looks similar to an activity, but has different life cycle callback methods. The fragment below accomplishes the same thing as the activity example above: it sets up a view.

Fragment 类是在 Honeycomb(译注:蜂巢 3.0 API level 11)发布时被介绍的。它容许咱们把应用组件分解成可重用的部件。Fragment必须被一个 activity 托管,而一个 activity 能够一次托管一个或多个 fragment。

一个简单的 fragment 看起来和 activity 很像,可是具备不一样的生命周期回调方法。下面的 fragment 代码段和上面的 activity 代码段完成了相同的事情:创建视图。

public class MainFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_main, container, false);
    }
}

As you can see, activities and fragments look very similar and are both used to construct applications. So, what are the advantages that come with the use of Fragments?

如你所见,activities 和 fragments 看起来很是像,一样被用于构建app。因此,使用 fragments 能够带来什么优点呢?且听我一一道来:

Device Optimization 设备优化

As I mentioned before, fragments were introduced with the Honeycomb release of Android. Honeycomb was the first version of Android with official support for tablets. One of the original goals of the fragment concept was to help developers make applications that provide different user experiences on phones and tablets.

The canonical example of fragment use is an email client. Let’s take a look at the Gmail app. When running on a phone, the Gmail app will display a list of the user’s emails. Tapping on one of these emails will transition the screen to showing the detail view for that particular email. This process is composed of two separate screens.

When using the same app on a tablet, the user will see both the email list and the detail view for a single email on the same screen. Obviously, we can show much more information at once with a tablet.

Fragments make implementing this functionality easy. The list of emails would exist in one fragment, and the detail view for an email would exist in another fragment. Depending on the device size, our activity will decide to show either one or both of these fragments.

The beauty of fragments here is that we do not have to modify either of these Fragment classes for this to happen. Fragments are reusable components of our application that can be presented to the user in any number of ways.

我刚刚讲过,Honeycomb 发布时引入了 fragments。Honeycomb 版本首次对平板设备提供了正式支持。fragment 理念的最初目标之一是帮助开发者在构建手机和平板应用时提供不一样的用户体验。

邮件客户端是用到 fragment 的典型例子,好比 Gmail App。手机版展现了用户的邮件列表,点击其中一个就跳转到展现邮件内容的详情界面。这个过程包含了两个界面,各自独占屏幕。

当用户在平板上使用 Gmail App 时,能够在一个屏幕上同时看到列表界面和详情界面。显然咱们能够在平板上一次显示更多的信息。

Fragments 很容易实现这个功能。列表界面是一个 fragment,详情界面也是一个 fragment。activity 根据屏幕大小决定显示其中一个或所有。

Fragments 的优雅之处在于,不须要修改 fragment 类的代码就能够完成上述事情。做为 app 的可重用组件,fragments 能够以任意多种方式呈现给用户。

Figure 1 Fragments in use on a tablet

So, this is great, but what if you aren’t developing an app that works on phones and tablets? Should you still use fragments?

The answer is yes. Using fragments now will set you up nicely if you change your mind in the future. There is no significant reason not to start with fragments from the beginning, but refactoring existing code to use fragments can be error-prone and will take time. Fragments can also provide other nice features besides UI composition.

这很是棒,但若是你开发的应用不须要兼容手机和平板,还须要使用 fragments 吗?

答案是『yes』。若是未来你改变了主意(译注:结合上下文,应该理解为须要大刀阔斧地改代码),你会庆幸当初使用了 fragments。从一开始并无特别的理由不使用 fragments,可是为了使用 fragments 而重构已有的代码,将是耗时且容易出错的。除了构成UI外,Fragments 还提供了一些其它优秀特性。

ViewPager

For example, implementing a ViewPager is very easy if you use fragments. If you’re not familiar with ViewPager, it’s a component that allows the user to swipe between views in your application. This component is used in many apps, including the Google Play Store app and the Gmail app. Swiping just swaps out the fragment that the user is seeing.

ViewPager hits at one of the core ideas behind fragments. Once your application-specific code lives in fragments, those fragments can be hosted in a variety of ways. The Fragment is not concerned with how it’s hosted; it just knows how to display a particular piece of your application. Our activity class that hosts fragments can display one of them, multiple Fragments, or use some component like a ViewPager that allows the user to modify how the fragment is displayed. The core pieces of code in your app do not have to change in order for you to support all of these different display types.

好比,使用 fragments 能够很方便地实现 ViewPager。若是你不熟悉 ViewPager,那我就简单说说,它做为一个应用组件,容许用户滑动屏幕以切换界面。不少 app 用到了它,包括 Google Play Store app 和 Gmail app。滑动屏幕就置换了当前的 fragment。

ViewPager 瞄准了 fragments 的一个核心理念。一旦你的特定的应用代码存在于 fragments,这些 fragments 就能够以多种方式被托管。Fragment 不需关心如何被托管,它只需知道如何展现你的应用的特定部分。托管 fragments 的 activity 类,能够显示一个 fragment;或者多个 fragment;或者像 ViewPager 那样经过某种方式显示 fragments。不须要修改应用的核心代码就能够支持这些不一样的显示方式。

Other Features 其它特性

So, Fragments can help us optimize our applications for different screen sizes and they help us provide interesting user experiences. There are other features that Fragments can help with as well.

You can think of Fragments as a better-designed version of an activity. The life cycle of a Fragment allows for something that Activities do not: Separation of the creation of the View component from the creation of the controller component itself.

因此 fragments 能够帮助咱们优化应用以适应不一样的屏幕尺寸,能够帮助咱们为用户提供有趣的体验。除此以外,它的其它特性也能够帮到咱们。

你能够把 fragment 看成一个『设计更合理』的 activity。Fragments 的生命周期容许它作一些 activity 作不到的事情:它分开了实例的建立和视图的建立。

译注:做者是指 Fragment 具备 onCreate(...), onCreateView(...), onDestroyView() 等生命周期方法,这些方法使得 fragment 拥有了分开建立实例和视图、以及保存实例而仅销毁视图的能力。而 Activity 的 onCreateView(...) 并非生命周期回调方法。

onCreate(Bundle) called to do initial creation of the fragment.
onCreateView(LayoutInflater, ViewGroup, Bundle) creates and returns the view hierarchy associated with the fragment.
onDestroyView() allows the fragment to clean up resources associated with its View.

译注部分结束。

This separation allows for the existence of retained fragments. As you know, on Android, rotating your device is considered a configuration change (there are a few other types of configuration changes as well). This configuration change triggers a reload of Activities and Fragments so that resources can be reloaded for that particular configuration. During the reload, these instances are completely destroyed and then recreated automatically. Android developers have to be conscious of this destruction because any instance variables that exist in your activity or fragment will be destroyed as well.

Retained fragments are not destroyed across rotation. The view component of the fragments will still be destroyed, but all other state remains. So, fragments allow for the reloading of resources across rotation without forcing the complete destruction of the instance. Of course, there are certain situations where this is and is not appropriate, but having the option to retain a fragment can be very useful. As an example, if you downloaded a large piece of data from a web server or fetched data from a database, a retained fragment will allow you to persist that data across rotation.

这种『分离』容许咱们保存 fragment 实例。你知道的,旋转 android 设备屏幕被认为是设备配置发生了变化(配置变化还包括其它几种)。系统会寻找更合适的资源以匹配配置,这个过程当中 activities 和 fragments 实例会被系统销毁,而后新的实例会被建立。android 开发者必须考虑这种销毁的情形,由于保存在 activity 和 fragment 中的全部实例变量也一样被销毁了。

『Retained fragments』在设备旋转时实例不会被销毁,仅仅是视图被销毁了,其它全部状态都会被保存下来。尽管有一些情形并不适用,retained fragment 还是十分有用的(译注:调用 setRetainInstance(true) 使 fragment 成为 retained fragment)。举个栗子,若是你从网络服务器或者数据库下载大量数据,retained fragment 在设备旋转时仍持有已下载的数据。

Additional Code 额外的代码

When you use fragments to construct your Android application, your project will contain more Java classes and slightly more code than if you did not use fragments at all. Some of this additional code will be used to add a fragment to an activity, which can be tricky if you don’t know how the system works.

Some Android developers, especially those who have been developing Android applications since before Honeycomb was released, opt to forego using Fragments. These developers will cite the added complexity when using Fragments and the fact that you have to write more code. As I mentioned before, the slight overhead that comes with fragment use is worth the effort.

与不使用 fragments 相比,当你使用 fragments 构建 android app 时,你的项目会包含更多的 Java 类和略多的代码。多出来的部分代码用于把 fragment 添加给 activity,若是你不熟悉其中的机制,会至关棘手。

一些 android 开发者,特别是那些在 Honeycomb 发布前就已经在开发 android app 的,选择放弃使用 fragments。使用 fragments 带来的复杂度和须要写更多的代码是这些开发者的理由。但正如我以前所讲,使用 fragments 须要付出的这点儿努力是值得的。

Embracing Fragments 涌抱它

Fragments are a game changer for Android developers. There are a number of significant advantages that come with Fragment-based architectures of Android applications, including optimized experiences based on device size and well-structured, reusable code. Not all developers have embraced fragments, but now is the time. I highly recommend that Android developers make generous use of fragments in their applications.

对于 Android 开发者而言,fragments 是一个拐点。基于 fragment 构建的应用带来显著的优点,包括基于屏幕尺寸来优化体验、结构良好和可重用的代码。并不是全部的开发者涌抱了 fragments,不过如今,时候到溜(译注:吴吞也是这样说滴)。我强烈建议 android 开发者大量使用 fragments。



译后:安利我本身的几篇关于 Fragment 的总结笔记:

来来来 让咱们一块儿涌抱Fragment 一块儿high


版权声明:《「译」向Big Nerd Ranch提问:为何Fragment在Android App开发中很是重要?》由 WeiYi.Li 在 2015年12月04日写做。著做权归做者全部。商业转载请联系做者得到受权,非商业转载请注明出处。
文章连接:http://li2.me/2015/12/why-do-fragments-m...

相关文章
相关标签/搜索