本頁將提供優化應用程式,以提升其在大螢幕裝置上表現的建議。

Flutter(如同 Android)將大螢幕定義為平板電腦、可折疊裝置,以及執行 Android 的 ChromeOS 裝置。Flutter 同時 也將 Web、桌面與 iPad 視為大螢幕裝置。

使用 GridView 進行版面配置

#

請參考下方應用程式的螢幕截圖。 該應用程式將其 UI 顯示於ListView中。 左側圖片顯示應用程式運行於行動裝置上,右側圖片則為 應用程式運行於大螢幕裝置上(尚未套用本頁建議)。

Sample of large screen

這樣的呈現並不理想。

Android 大螢幕應用程式品質指引 以及iOS 對應指引 都建議:文字或方塊不應佔據整個螢幕寬度。那麼,如何以自適應方式解決這個問題?

常見的解決方案是使用GridView,如下節所示。

GridView

#

你可以使用GridView元件,將現有的ListView轉換為更合理尺寸的項目。

GridView類似於ListView元件, 但不僅能處理線性排列的小元件清單, GridView還能將元件排列為二維陣列。

GridView也有與ListView類似的建構函式。 ListView的預設建構函式對應到GridView.count, 而ListView.builder則類似於GridView.builder

GridView還有一些額外的建構函式,可用於更自訂的版面配置。 想了解更多,請參閱 GridView API 文件頁面。

例如,若你的原始應用程式使用ListView.builder, 可以將其替換為GridView.builder。 如果你的應用程式有大量項目, 建議使用這個 builder 建構函式,僅建立實際可見的項目元件。

兩個元件的建構函式大多數參數都相同,因此替換起來相當直接。 但你需要決定gridDelegate的設定值。

Flutter 提供了強大的預設gridDelegates, 你可以直接使用,分別為:

SliverGridDelegateWithFixedCrossAxisCount
讓你為網格指定固定的欄數。
SliverGridDelegateWithMaxCrossAxisExtent
讓你定義項目的最大寬度。

其他解決方案

#

另一種做法是利用BoxConstraintsmaxWidth屬性。 這包含以下步驟:

  • 使用ConstrainedBox包裹GridView,並給予 一個設定最大寬度的BoxConstraints
  • 如果你需要設定背景顏色等其他功能,請用Container取代ConstrainedBox

在選擇最大寬度時, 建議參考 Material 3 的 Applying layout 指南中推薦的數值。

可折疊裝置(Foldables)

#

如前所述,Android 與 Flutter 的設計指引都不建議 鎖定螢幕方向, 但有些應用程式仍會鎖定螢幕方向。 請注意,這麼做可能會在可折疊裝置上造成問題。

當應用程式運行於可折疊裝置時,裝置折疊時看似正常。 但展開裝置時,應用程式可能會出現 letterbox(信箱模式)現象。

SafeArea & MediaQuery 頁面所述, letterboxing 意指應用程式視窗被鎖定在螢幕中央, 四周則以黑色填充。

為什麼會發生這種情況?

這通常發生於你使用MediaQuery來取得應用程式視窗大小時。 當裝置處於折疊狀態時,螢幕方向會被限制為直向模式。 在底層,setPreferredOrientations會讓 Android 使用直向相容模式,應用程式因此以 letterbox 狀態顯示。 在 letterbox 狀態下,MediaQuery永遠不會收到 允許 UI 擴展的較大視窗尺寸。

你可以用以下兩種方式解決:

  • 支援所有螢幕方向。
  • 使用_實體螢幕_的尺寸。 事實上,這是少數幾個 你應該使用實體螢幕尺寸而_不是_視窗尺寸的情境之一。

那麼,如何取得實體螢幕尺寸?

你可以使用 Display API(自 Flutter 3.13 起提供), 它包含裝置的尺寸、像素比與更新率等資訊。

以下範例程式碼會取得Display物件:

dart
/// AppState object.
ui.FlutterView? _view;

@override
void didChangeDependencies() {
  super.didChangeDependencies();
  _view = View.maybeOf(context);
}

void didChangeMetrics() {
  final ui.Display? display = _view?.display;
}

重要的是要找到你關心的 view 的顯示方式。這樣可以建立一個前瞻性的 API,能夠因應目前以及未來的多顯示器與多 view 裝置。

自適應輸入(Adaptive input)

#

支援更多螢幕,也代表要擴展輸入控制方式。

Android 指南將大型裝置的支援分為三個層級。

3 tiers of large format device support

第 3 層(最低層級的支援)包含對滑鼠與觸控筆輸入的支援 (Material 3 指南Apple 指南)。

如果你的應用程式使用 Material 3 及其按鈕與選擇器, 那麼你的應用程式已經內建支援 多種額外的輸入狀態。

但如果你有自訂元件(Widget)呢? 請參考 User input 頁面, 取得如何為 元件加入輸入支援 的指引。

導覽(Navigation)

#

在面對各種不同尺寸裝置時,導覽會帶來獨特的挑戰。一般來說,你會根據可用螢幕空間,在 BottomNavigationBarNavigationRail 之間切換。

如需更多資訊(以及對應的範例程式碼), 請參考 Problem: Navigation rail,這是 Developing Flutter apps for Large screens 文章中的一節。