大多數真實世界的應用都需要適應不同裝置和平臺的功能和策略。本頁包含有關如何在程式碼中處理這些場景的建議。

根據每種裝置型別的優勢進行設計

#

考慮不同裝置的獨特優勢和劣勢。除了螢幕尺寸和輸入(例如觸控、滑鼠、鍵盤)之外,您還可以利用哪些其他獨特功能?Flutter 使您的程式碼能夠在不同的裝置上 執行,但強大的設計不僅僅是執行程式碼。思考每個平臺最擅長什麼,並檢視是否有獨特的功能可以利用。

例如:Apple 的 App Store 和 Google 的 Play Store 有不同的應用需要遵守的規則。不同的宿主作業系統在不同時間以及彼此之間也具有不同的功能。

另一個例子是利用網路極低的分享門檻。如果您正在部署一個 Web 應用,請決定支援哪些深層連結,並以此為念來設計導航路由。

Flutter 推薦的根據這些獨特功能處理不同行為的模式是為您的應用建立一組 CapabilityPolicy 類。

功能

#

功能 (capability) 定義程式碼或裝置 可以 做什麼。功能的例子包括:

  • API 的存在
  • 作業系統強制的限制
  • 物理硬體要求(如攝像頭)

策略

#

策略 (policy) 定義程式碼 應該 做什麼。

策略的例子包括:

  • 應用商店指南
  • 設計偏好
  • 引用宿主裝置的資源或文字
  • 伺服器端啟用的功能

如何組織策略程式碼

#

最簡單的機械方式是 Platform.isAndroidPlatform.isIOSkIsWeb。這些 API 機械地告訴您程式碼在哪裡執行,但隨著應用執行範圍的擴大以及宿主平臺新增功能,它們會遇到一些問題。

以下準則解釋了開發應用功能和策略時的最佳實踐

避免使用 Platform.isAndroid 和類似函式來做出佈局決策或對裝置功能做出假設。

相反,在方法中描述您希望分支的內容。

示例:您的應用有一個在網站上購買商品的連結,但出於政策原因,您不想在 iOS 裝置上顯示該連結。

dart
bool shouldAllowPurchaseClick() {
  // Banned by Apple App Store guidelines. 
  return !Platform.isIOS;
}

...
TextSpan(
  text: 'Buy in browser',
  style: new TextStyle(color: Colors.blue),
  recognizer: shouldAllowPurchaseClick ? TapGestureRecognizer()
    ..onTap = () { launch('<some url>') : null;
  } : null,

透過增加一層間接性,您獲得了什麼?程式碼更清楚地說明了分支路徑存在的原因。這個方法可以直接存在於類中,但程式碼的其他部分可能也需要相同的檢查。如果是這樣,將程式碼放入一個類中。

policy.dart
dart

class Policy {

  bool shouldAllowPurchaseClick() {
    // Banned by Apple App Store guidelines. 
    return !Platform.isIOS;
  }
}

將此程式碼放在一個類中,任何 widget 測試都可以模擬 Policy().shouldAllowPurchaseClick 並獨立於裝置執行位置驗證行為。這也意味著,如果以後您決定在網上購買對於 Android 使用者來說不是正確的流程,您可以更改實現,而可點選文字的測試無需更改。

功能

#

有時您希望程式碼做某事,但 API 不存在,或者您依賴的外掛功能尚未在您支援的所有平臺上實現。這是裝置 可以 做什麼的限制。

這些情況類似於上面描述的策略決策,但它們被稱為 功能 (capabilities)。為什麼將策略類與功能分離,而類的結構相似?Flutter 團隊在生產化應用中發現,在應用 可以 做什麼和 應該 做什麼之間做出邏輯區分,有助於大型產品在初始程式碼編寫後,除了您自己的偏好之外,還能應對平臺功能或要求的變化。

例如,考慮一種情況,一個平臺添加了一個新許可權,要求使用者在您的程式碼呼叫敏感 API 之前與系統對話方塊互動。您的團隊為平臺 1 完成了工作,並建立了一個名為 requirePermissionDialogFlow 的功能。然後,如果平臺 2 添加了類似的要求,但僅適用於新的 API 版本,那麼 requirePermissionDialogFlow 的實現現在可以檢查 API 級別併為平臺 2 返回 true。您已經利用了您已經完成的工作。

策略

#

我們鼓勵您最初從一個 Policy 類開始,即使看起來您不會做出很多基於策略的決策。隨著類的複雜性增加或輸入數量擴充套件,您可能會決定按功能或其他標準拆分策略類。

對於策略實現,您可以使用編譯時、執行時或遠端過程呼叫 (RPC) 支援的實現。

編譯時策略檢查適用於偏好不太可能改變且意外更改值可能帶來嚴重後果的平臺。例如,如果某個平臺要求您不得連結到 Play 商店,或者要求您根據應用內容使用特定的支付提供商。

執行時檢查可以很好地確定使用者是否可以使用觸控式螢幕。Android 有一個可以檢查的功能,您的 Web 實現可以檢查最大觸控點。

RPC 支援的策略更改適用於增量功能釋出或可能稍後更改的決策。

概述

#

使用 Capability 類定義程式碼 可以 做什麼。您可以檢查 API 的存在、作業系統強制的限制和物理硬體要求(如攝像頭)。功能通常涉及編譯時或執行時檢查。

使用 Policy 類(或根據複雜程度使用多個類)定義程式碼 應該 做什麼以遵守應用商店指南、設計偏好以及需要引用宿主裝置的資源或文字。策略可以是編譯時、執行時或 RPC 檢查的混合。

透過模擬功能和策略來測試分支程式碼,這樣當功能或策略改變時,widget 測試就不需要改變。

根據它們試圖分支的內容,而不是根據裝置型別,命名功能和策略類中的方法。