Coordinators探險——fragment和viewGroup的抉擇

Coordinators簡介

2個月前,square開源了Coordinators。這個項目的作用在主頁的第一句話寫得很清楚:

Simple lifecycle for your MVWhatever on Android. No kidding.

講真,簡化Android開發中MV**模式里的生命周期。

項目的使用也十分簡單,首先讓你的界面控制層繼承Coordinator

所謂控制層:MVVM里就是ViewModel,MVP里就是Presenter

class Whaterver extends Coordinator {

  @Override public void attach(View view) {
    // Attach listeners, load state, whatever.
  }

  @Override public void detach(View view) {
    // Unbind listeners, save state, go nuts.
  }
}

然后把你的控制層和界面進行綁定:

// Create a factory for your Coordinators.
CoordinatorProvider coordinatorProvider; // @Nullable (View) -> Coordinator

// Bind a Coordinator to a View.
Coordinators.bind(view, coordinatorProvider);

// Bind a Coordinator to any child View added to a group.
Coordinators.installBinder(viewGroup, coordinatorProvider);

綁定方法可以看見,綁定的對象不是比較高級頁面對象ActivityFragment,而是更底層的View或者ViewGroup

Android的界面顯示組件

首先簡單介紹一下Android的各個界面顯示組件:

1.Activity
Android里最基本的頁面組件,基本上每一個全屏頁面都是一個ActivityActivity并不顯示具體的內容,而只是一個簡單的容器,容器內部包含了各種ViewViewGroup

2.ViewViewGroup

  • View就是顯示的基本控件,包括按鈕,文本框,圖片框等等。

  • ViewGroup的性質類似html中的div,其內部包含了各種ViewViewGroup。然后整體被放進了Activity中:

+------------------+
|    Activity      |
|                  |
|    +-------+     |
|    | View  |     |
|    | Group |     |
|    +-------+     |
|                  |
+------------------+

最初Android的展示界面就是這兩種。隨著應用界面的復雜度不斷升高,加上單頁應用的體驗比多頁更加優秀,Activity內代碼也隨之不斷增多。

3.Fragmnet
為此,谷歌推出了Fragment,這個組件可以像Activity一樣包含ViewGroup,同時又能像ViewGroup一樣被添加到Activity中。這樣開發者只需要把原來繼承Activity的內容修改為繼承Fragment,然后通過配套的Api把多個Fragment添加到一個Activity中。就能快速的將一個多頁應用改造成一個單頁應用。

+--------------------+
|     Activity       |
|                    |
|    +----------+    |
|    | Fragment |    |
|    +----------+    |
|                    |
+--------------------+

+------------------+
|    Fragment      |
|                  |
|    +-------+     |
|    | View  |     |
|    | Group |     |
|    +-------+     |
|                  |
+------------------+

同時開發者依然可以遵循原來的Activity開發習慣,繼續基于Fragment開發應用。

這看起來很美妙,但Android存在一個令人抓狂的概念——生命周期

生命周期

聲明周期描述的是一個頁面從打開到銷毀經歷的各個過程,在各個過程里系統都會通過方法告知開發者。就Activity來說,開發者主要關心的方法大概有:

onCreate() // 界面創建
    ↓
onResume() // 準備顯示
    ↓
onPostResume() // 顯示完成
    ↓
onPause() // 從屏幕消失
    ↓
onDestory() // 被系統銷毀

這只是大概,還有一些特殊情況,例如在被系統銷毀前再次打開應用,還會多觸發一些事件。但這種復雜度對于大多數人還在可以接受范圍內。

但是,在引入Fragment之后,

首先Fragment和Activity并不完全相同,在使用方面會有一些坑需要躲避;

其次由于Fragment也有生命周期的概念,一方面,Fragment需要跟隨Activity進行顯示隱藏;另一方面Fragment會被開發者動態的添加/移除,因此他又有自己需要獨立的生命周期事件:

有一個專門的github項目android-lifecycle整理了各個生命周期的關系

來感受一下:

complete_android_fragment_lifecycle.png

對于生命周期,大部分情況下,開發者僅僅關注應用的打開和關閉事件。但引入Fragment后需要增加更多的開發測試成本。例如Fragment如果存在于翻頁組件中,當前頁被翻走后,我們可能會認為將會觸發Fragment的onPause事件,而實際上,觸發的是onHiddenChange事件。

封裝ViewGroup

回到最初Activity遇到的問題。我們不引入Fragment,而直接使用ViewGroup

+------------------+
|    Activity      |
|                  |
|    +-------+     |
|    | View  |     |
|    | Group |     |
|    +-------+     |
|                  |
+------------------+

+------------------+
|    ViewGroup     |
|                  |
|    +-------+     |
|    | View  |     |
|    | Group |     |
|    +-------+     |
|                  |
+------------------+

并且從面向Activity開發轉為面向ViewGroup開發。ViewGroup的生命周期事件只有兩個:onAttachonDetach,分別在被添加到屏幕和被移除時調用。而遇到特殊的事件,我們就需要通過手動的方式從Activity中往ViewGroup里傳遞。對比Fragment

缺點:

  • 舊的Activity無法方便遷移到Fragment里
  • 需要手動傳遞特殊的聲明周期事件(例如onActivityResult)

優點:

  • 因為僅有最簡單的生命周期,所以完全不會造成迷惑
  • 不需要學習Fragment復雜的生命周期和Api

Coordinators

Coordinators項目實際上只有5個小文件,他做的僅僅是把ViewGroup的兩個生命周期提取到他的Coordinator類里,讓開發者面向Coordinator類來進行開發。

所以與其說他是一個框架,不如說是一種約束: 既然Activity里內容太多,那就只提供一個能把Activity中內容分隔開的組件,這個組件不需要有太復雜太全面的功能,而僅僅是一個引導的作用。經過他的約束,開發者自然會規范自己的代碼。

Coordinators安利圖

總結

使用Fragment或者ViewGroup孰優孰劣實際上還是需要具體場景結合分析。

Fragment是官方推出的框架,他的特點就是大、全、嚴謹;而Coordinators更像一個規范代碼的工具類。都可以解決顯示組件模塊化問題。

我們在開發中往往也會遇到類似的代碼框架上的問題,為了修復這些問題,或許我們也會去考慮寫一個更完善的框架,或者引入一個新的概念和組件。

而Coordinators告訴我們,當遇到這種問題我們或許可以通過代碼約束的角度來解決。設計一些方法對出現問題的根本進行約束,或許在功能上有所損失,但對于使用者來說,學習成本降低或許能帶來更好的效果。

相關閱讀:

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容