譯者說: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, 禁止轉載
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 能夠帶來什麼優點呢?且聽我一一道來:
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 能夠以任意多種方式呈現給用戶。
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 還提供了一些其它優秀特性。
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。不須要修改應用的核心代碼就能夠支持這些不一樣的顯示方式。
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 在設備旋轉時仍持有已下載的數據。
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 須要付出的這點兒努力是值得的。
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...