在 Flutter 中,隨機顏色是任何透過為紅色、綠色和藍色通道各繪製 0 到 255 之間的整數,然後將它們傳入 `Color.fromARGB(255, r, g, b)` 或簡寫建構函式 `Color(0xFFRRGGBB)` 所產生的 `Color` 值。Flutter 隨附 `dart:math` 函式庫,其中提供一個 `Random` 類別,能夠以單行程式碼產生這些整數,因此開發人員在簡單的情況下很少需要第三方套件。根據 MDN 關於 CSS 顏色值的文件,以每通道 8 位元表示的 RGB 模型是螢幕顏色的主流表示方式,而 Flutter 一對一地鏡像了該模型,這就是為什麼貼上的 HEX 值可以乾淨地對應到 Dart 程式碼中。

開發人員通常出於以下三個原因之一而希望在 Flutter 中使用隨機顏色:在等待設計師的設計標記時建立佔位 UI、為螢幕擷圖和行銷素材產生示範資料,或是為一個點擊後背景會變更的互動小元件提供顏色。上述每種情境都有略微不同的理想解決方案,而本文的其餘部分將介紹原生程式碼、套件式程式碼,以及當你完全不想撰寫程式碼時最快速的設計優先方法。

how to generate random color in flutter
how to generate random color in flutter

使用 dart:math 產生隨機顏色

`dart:math` 函式庫屬於 Dart 核心的一部分,因此不需要在 `pubspec.yaml` 中新增任何內容。在要使用它的檔案頂端將其匯入,然後建立單一 `Random` 執行個體,並呼叫 `nextInt(256)` 三次以填入紅色、綠色和藍色通道。將結果與 alpha 值 255 包裝在 `Color.fromARGB` 中,以獲得完全不透明的色塊。

這種方法最具可攜性,也是最容易教給初學者的方法,因為它不使用任何外部依賴。當你將固定的 `seed` 傳遞給 `Random` 建構函式時,它也是確定性的,這使得它非常適合用於小元件測試中,讓你能夠斷言特定的顏色值,而不必模擬隨機來源。其缺點在於,在 RGB 空間上的分佈是均勻的,因此每 256 個顏色中大約會有一個接近黑色,另一個接近白色;比起設計師青睞的調色盤,你會更常得到混濁的中間色調。

使用 pub.dev 上的 random_color 套件

為了獲得美觀的輸出,pub.dev 上的 random_color 套件包裝了 David Aerne 的「nice color」演算法,該演算法將產生結果偏向飽和、中等亮度的色相,這些色相在 UI 模型中看起來效果良好。將它加入你的依賴項目:

  • 開啟 `pubspec.yaml`,在 `dependencies:` 下加入 `random_color: ^2.0.0`(或 pub.dev 上顯示的最新版本)。
  • 執行 `flutter pub get` 以擷取該套件。
  • 使用 `import 'package:random_color/random_color.dart';` 將其匯入。
  • 呼叫 `RandomColor().randomColor()` 即可接收一個可用於任何小元件的 `Color`。

該套件接受 `colorSaturation`、`colorBrightness` 和 `colorHue` 等選項,讓你能夠將輸出範圍縮小至柔和色調、深色模式色塊或單一色相系列。它還提供 `randomColors(count: 20)` 方法,可在單次呼叫中回傳一個 `List<Color>`,當你需要用於圖表或清單檢視的快速調色盤時非常實用。由於該演算法由社群維護,因此非常適合用於原型和示範應用程式,但不適合用於品牌顏色固定的生產設計系統。

使用 setState 觸發顏色變更

產生隨機顏色本身在螢幕上不會產生任何效果,除非框架重新建置。在 `StatefulWidget` 中,將顏色儲存在一個欄位中,並在需要新值時呼叫 `setState`:

  1. 在你的 `State` 類別上將 `Color _bg = const Color(0xFFFFFFFF);` 宣告為一個欄位。
  2. 在 `onPressed`、`onTap` 或 `onLongPress` 處理常式內部,執行賦值 `_bg = RandomColor().randomColor();`(或你的 `dart:math` 等效寫法)。
  3. 在賦值後立即呼叫 `setState(() {})`,以便 Flutter 將小元件標記為髒污狀態並排定一個畫面。
  4. 將 `_bg` 綁定到你的小元件樹狀結構中 — 例如,在 `AppBar` 上使用 `backgroundColor: _bg`,或在 `Container` 上使用 `color: _bg`。

如果你正在使用 Provider、Riverpod 或 Bloc 等狀態管理函式庫,則改為透過該系統公開顏色,並在值變更時重新建置消費方小元件。產生邏輯完全相同;只是重新建置機制不同。

將選取的 HEX 值轉換為 Flutter 顏色

設計師通常會以六位數 HEX 字串(例如 `#3B82F6`)的形式提供顏色。Flutter 可透過 `Color` 建構函式直接接受這些字串,只需在前面加上 `0xFF` 並移除井字號即可:`Color(0xFF3B82F6)`。`0xFF` 部分將 alpha 設定為完全不透明,這正是你對純色背景和填色所期望的效果。

對於需要處理 alpha 的顏色,請使用八位數形式 `Color(0xAARRGGBB)` 或具名建構函式 `Color.fromARGB(a, r, g, b)`。開頭的兩個十六進位數字接著控制透明度,其中 `00` 表示完全透明,`FF` 表示完全不透明。這與 MDN 中關於十六進位顏色的參考資料所描述的模型相同,因此從 CSS 轉過來的設計師會感到熟悉。

如果你寧願跳過手動轉換,直接取得可用的 HEX 值,可以開啟隨機顏色產生器,點擊任何色塊即可複製其 HEX,然後直接將其貼入 `Color(0xFF...)`。當你需要用於文件或設計交接的 RGB 和 HSL 字串格式時,該色塊也會提供這些格式。

為你的情境選擇合適的方法

情境建議方法為何合適
單元測試和小元件測試來自 `dart:math` 的 `Random(seed: 42)`確定性的輸出使斷言在各次執行間保持穩定。
原型或示範應用程式`random_color` 套件無需設計輸入即可產生視覺上令人愉悅的調色盤。
生產品牌顏色硬編碼的 `Color(0xFF...)` 常數品牌指南絕不應依賴於隨機性。
點擊變更的互動`setState` 內部的 `dart:math`輕量、零依賴,可在每個畫面預算內執行。
行銷螢幕擷圖線上產生器 + 貼上 HEX讓設計師無需撰寫程式碼即可挑選精確的色塊。

在不產生不穩定測試的情況下測試隨機顏色

未植入種子的隨機產生是穩定測試套件的敵人。如果小元件測試預期特定的顏色,而實作使用的是新植入種子的 `Random`,則該測試可能執行一次通過,但下一次執行就會失敗。解決方法是注入 `Random` 執行個體 — 可以透過小元件的建構函式參數、`main.dart` 中的全域覆寫,或是 Riverpod 中的提供者 — 並在測試內部傳遞一個植入種子的值。你也可以將產生的顏色儲存在普通的 `Color?` 欄位中,然後斷言它不為 null 且落在有效的 0–255 範圍內,而不是檢查精確的 RGB 元組。

在 Flutter 中產生隨機顏色的常見陷阱

有三個錯誤經常出現。首先,在 `build` 內部呼叫 `Random()` 會在每次重新建置時建立新的隨機來源,這會破壞 `setState` 的效果並產生視覺閃爍。請將 `Random` 執行個體移至欄位或頂層 final 變數。其次,使用 `Color.fromRGBO` 搭配介於 0 到 1 之間的隨機 alpha 通常會產生不可見的小元件;如果你想要透明度,請從一組離散值中挑選,例如 `[0.2, 0.5, 0.8, 1.0]`。第三,同時匯入 `dart:math` 和 `flutter/material.dart` 會導致 `Color` 上的名稱衝突;可以為其中一個設定別名(`import 'dart:math' as math;`),或使用完整限定名稱 `math.Random()`。

將隨機顏色與工具組的其他部分搭配使用

單一的隨機色塊很少是故事的結局。一旦你擁有了喜歡的基底顏色,顏色調色盤產生器便會圍繞它建立互補、類似和三元等配色方案。若要檢查文字在你隨機背景上是否仍然清晰可讀,請將該組合傳入顏色對比檢查器。有關更多跨平台隨機顏色工作流程,請參閱我們關於在 JavaScript 中產生隨機顏色代碼以及快速的 CSS 方法的指南;對於試算表使用者而言,Excel 快速方法則會逐步介紹在儲存格中實現相同概念的做法。希望獲得靈感但無需撰寫任何程式碼的設計師可以瀏覽一鍵為設計專案產生隨機顏色,以取得精選的工作流程。