2012-03-22 102 views
63

使用Fragment比使用在不同佈局中重複使用的定製View有什麼優勢?爲什麼使用碎片?

original blog post introducing fragments,戴安娜Hackborn說

[片段]讓開發者更容易編寫能夠在該平臺秤在各種屏幕尺寸的 ,超越設施已經 可用的應用程序。

她繼續在爲應用程序製作平板電腦佈局的情況下解釋片段,該應用程序結合了來自同一應用程序的電話版本的兩個活動的UI。

但似乎可以使用自定義視圖實現相同的重用。片段和視圖之間的主要不同似乎是他們具有不同的生命週期...

Fragment生命週期:

onAttach()onCreate()onCreateView()onActivityCreated()onStart()onResume()onPause()onStop()onDestroyView()onDestroy()onDetatch()

View生命週期:

ctoronFinishInflate()onAttachedToWindow()onMeasure()onLayout()onDetatchedFromWindow()

我想從開發人員聽到有經驗寫什麼好處大的應用程序(如果有的話),他們」在使用片段vs自定義視圖將UI分解爲可重用片段方面見過。

回答

51

主要原因是片段比自定義視圖更可重用。

有時您不能單獨依靠視圖創建完全封裝的UI組件。這是因爲有些東西是你想放進你的視圖中的,但是不能,因爲只有一個Activity可以處理它們,因此強制活動和視圖之間的緊密耦合。

這是一個這樣的例子。比方說,你想創建一個可重用的UI組件,在很多事情中,它們都想要捕獲一張照片並對其進行處理。傳統上,您會啓動啓動相機並隨捕獲的圖像一起返回的意圖。

請注意,您的自定義UI組件不能完全封裝這一功能,因爲它必須依靠主辦活動的startActivityForResult因爲意見不接受活動結果(他們可以間接地燒透方面的意圖)。

現在,如果您想在不同的活動中重複使用自定義UI組件,那麼您將重複Activity.startActivityForResult的代碼。

片段另一方面乾淨地解決這個問題。

同樣,您的片段可以將項目添加到您的選項菜單中,傳統上只有一個活動可以完成。如果您的自定義視圖的狀態決定了菜單中的內容,這也可能很重要。

+0

很好的答案,在我找到你之前,必須通過3-4個類似的SO帖子。 – 2015-01-27 07:25:28

+0

「同樣,你的片段可以貢獻項目到你的選項菜單,」@numan如果你解釋這一點,這將是很大的幫助\ – Killer 2015-10-28 09:41:26

31

片段不僅僅是一個視圖。事實上,它甚至可以完全沒有看法。它可以包含各種各樣的東西,包括AsyncTasks,各種監聽器,文件和數據庫訪問等等。

將其視爲一項小型活動,但您可以在屏幕上使用它們中的多個,並與它們一起工作,包括在可見時與對方通信。

E.g.您可以在一個片段中顯示購物車列表,並在另一個片段中詳細顯示當前選定的購物車。然後,例如,更改詳細視圖中項目的數量,並可以通知列表視圖並更新列表視圖中的總價格。您可以完全協調像這樣的交互,例如,仍然只有其中一個在較小的屏幕設備上可見。

我重構了一個大型商業應用程序(> 15個活動)從活動到片段以獲得良好的平板電腦支持,我永遠不會開始一個沒有片段的新應用程序。

更新2016年2月雖然上述情況仍然如此,但碎片的複雜性導致許多人完全避免使用它們。較新的模式,如使用MVC方法和更強大的視圖提供了替代方案。正如他們所說...... YMMV。

+13

但我可以使用自定義視圖來實現您剛纔給出的示例。您可以讓視圖彼此通信,並檢查操作系統是否正在使用平板電腦或電話佈局。我看到人們用碎片做同樣的事情。用碎片而不是視圖實現它有什麼好處? – VIBrunazo 2012-08-21 19:37:47

+0

也許片段提供更多的支持過渡,動畫,並強制一些容器,如ViewPager,ActionBar和Tabs .. – Snicolas 2013-02-04 19:12:49

+1

@VIBrunazo在下面看到我的答案。 http://stackoverflow.com/a/14912608/909956 – 2013-02-16 16:44:50

0

自定義視圖比僅使用片段代替您的活動更有效。如果您決定使用活動和自定義視圖,則必須創建自定義視圖,然後必須在活動中實施相同的活動生命週期方法(對於片段使用非常類似的生命週期)。

使用片段還允許您將組件分離到它們自己的類(片段)中,而不是在單個活動中包含太多邏輯。讓我以一個例子爲例:

假設您正在實施雜誌閱讀器應用程序。使用片段,您可以創建一個片段:ArticleList(其中顯示文章列表)和另一個片段:ArticleDisplay,它處理顯示內容的邏輯。然後您可以指定這些片段應如何使用片段工具進行交互,以便在手持設備上,您可以使用全屏幕實時顯示ArticleDisplay,而在平板電腦上,您可以並排顯示片段。

如果您嘗試使用活動/自定義視圖,您將在整體活動中擁有這兩個碎片的邏輯,您必須編寫自定義視圖,並且您必須調試這個笨拙的怪物。

片段通常是編寫應用程序的更復雜和更強大的方式。他們可以做一切活動可以做的事情,等等。如果你不需要額外的功能,默認設置可能會讓你需要去的地方,而且工作量較少。

+2

就整體活動而言,爲什麼使用Fragments將控制器代碼簡單地分解爲其他POJO控制器類? – avh 2012-03-22 17:27:16

+0

這對Fragment中包含的邏輯起作用(並且您可能應該爲這兩個活動和碎片執行此操作),但是您仍遇到單個方法調用作爲(至少)兩個控件的入口點的問題流動,這是最好的分離出來。你只能覆蓋Android用來與你的類在一個地方進行通信的方法調用,所以如果你有一個單一的活動,你有一個OnCreateDialog()被調用兩組對話框,每個「屏幕」一個。 – 2012-03-22 17:32:13

+0

我還應該補充說,使用Fragment而不是Activity不會有任何缺點。這很可能不需要編寫任何額外的代碼來獲得與使用片段的Activity相同的行爲,並且如果您需要 – 2012-03-22 17:33:59

3

生命週期方法可能是您最大的暗示。如果你仔細想想,它們與活動生命週期密切相關(對活動和視圖有一些掛鉤)。事實上,你鏈接的文章中,Hackborn說:

在你能想到的一個片段作爲一個小型的活動

與軟件設計/開發很多東西從某種角度來說,也有多種方式來做事情。有很多不同的地方你可以把你的代碼。是的,你可能會把很多東西放在一個視圖中,但是把不同的關注點分開放在不同的類中是件好事。這種經典模式是MVC,適用於這種情況。你不想在你的視圖中使用太多的控制器邏輯。最好將它保存在類似控制器的類中,這些類是活動和現在的片段。這就是爲什麼片段的生命週期更像活動而不是視圖 - 它是爲了促進這種組織而製作的。

+2

似乎片段和活動都在MVC中扮演控制器的角色。爲什麼不使用POJO類作爲分割控制器而不是片段的方式? – avh 2012-03-22 17:28:41

6

一些介紹:

想象活動作爲保持一個大蛋糕板。 片段將是一個容器,將同一塊蛋糕切成塊。 每片包含它自己的邏輯(聽衆等)。 總的來說,它們與一個大蛋糕幾乎沒有區別。

好處:

  1. 當板無法容納一個大蛋糕。 (屏幕很小)您可以輕鬆使用一些板塊(活動)來保存每個板塊,而無需將您的邏輯移動到新活動中。

  2. 更好的重用性。我有一些實例可以在另一個App中完全重用一個片段。您可能會聲稱自定義視圖也可以這樣做。但請參考第1點,我可以重新使用它,只需要幾行佈局更改,但對於自定義視圖,它必須找到一種方法將其插入到佈局和代碼中。

  3. 從某種意義上說,這是在Android編程中組織UI邏輯的更多OO方法。當你有一個功能(例如屏幕上的一個新分區)時,你可以創建一個新的Fragment類,並對現有的活動類進行微小的修改。但是,如果您只在活動中進行編程,則需要添加邏輯並對受測試的類進行大的修改。

只是我2美分。 :)

+1

但是,您可以輕鬆地將邏輯封裝在每片蛋糕中,而不需要使用片段。我可以做一個很好的乾淨的活動,只會有一兩行代碼創建和實現一塊蛋糕。所有的邏輯將在蛋糕類 – jonney 2013-05-02 17:10:51

+0

因此,所有的碎片都只是一種** XML與相關的Java源代碼**,並有一個獨立於外部世界的包內?除此之外,我的意思是,如果我們可以想象一個情況,那就是從源代碼創建的圖形,我們可以使用常規的類。 *順便說一下,在Scala中,有一種非常好的方法可以通過使用特性來解決這些問題!* – 2014-03-23 14:51:14

+0

這個問題實際上是關於片段vs視圖,而不是片段與活動。 – user3614314 2015-06-05 16:25:36

0

我碰過一次碎片,發現它們不是很有用(請參閱this post)。根據我讀到的,片段對於可以訪問活動環境的對象來說確實是一個奇特的詞。我喜歡在我的工作中忽略碎片,並自己創建這些對象。我通過向構造函數傳遞Activity而不是Context來創建非常大且要求非常苛刻的應用程序。然而,使用Fragments的一個主要好處是它們受到View佈局系統的支持 - 因此您可以輕鬆將它們添加到Android xml(如果您將它用於佈局)。

相關問題