0%

【文章內容使用 Gemini 1.5 Pro 自動翻譯產生】

大型 Dart 專案的漸進式空安全遷移

對於一個簡單的小套件來說,Dart 空安全遷移 需要 1-2 個小時的工作量,但對於一個大型專案來說,這可能是一場長達數月的馬拉松。理想情況下,您希望逐步遷移您的專案——在馬拉松期間,您希望保持您的專案可擴展、可維護且易於發佈。

我已經將一個大型專案遷移到空安全,並決定整理一些步驟和技巧,以說明如何使遷移過程可靠且高效,希望它能節省您的時間。

步驟 1:轉換為非健全的空安全

首先,將您的專案遷移到非健全的空安全

首先將您的依賴項升級到空安全版本。非健全的空安全並不要求所有依賴項都是空安全的。但是,強烈建議等到所有上游依賴項都遷移完畢後再進行遷移,因為遷移依賴項可能會迫使您重新審視您自己程式碼中的遷移決策。對於相互依賴的套件,您可能被迫無序遷移,或者同時遷移這些套件(許多相互依賴的套件大多只在測試中相互引用)。請遵循 dart.dev 上的指南 在遷移程式碼之前盡可能升級更多依賴項。

接下來,更新套件的 Dart SDK,並使用以下步驟將每個未遷移的函式庫標記為 legacy:

  1. 確保您的 IDE(VSCode、IntelliJ / Android Studio)已安裝 Dart 外掛。
  2. 在 IDE 中打開您的套件,並確保沒有編譯錯誤。
  3. 更新 pubspec.yaml 檔案中的 dart_sdk 依賴項,以要求版本範圍:>=2.12.0 <3.0.0
  4. IDE 將突出顯示尚未啟用空安全的函式庫中的空安全相關錯誤。透過在每個受影響檔案的頂部加入註釋 // @dart=2.9 來移除錯誤。即使您的 main.dart 檔案沒有錯誤,也要將註釋加入其中,以保持應用程式以非健全模式運行,直到您準備好切換為止。
  5. 驗證所有測試是否通過,並將變更提交到您的主分支。如果您的測試已經是空安全的,您將需要命令列標誌 --no-sound-null-safety 來抑制空安全錯誤。

啟動應用程式時,請確保您在控制台中看到「以非健全的空安全模式運行」。

現在您已準備好一次遷移一個函式庫到健全的空安全。

步驟 2:迭代到健全的空安全

選擇一個或一組要遷移的函式庫。

專業提示:如果您選擇的函式庫很大,您可能希望在遷移之前將其分解成較小的函式庫。

使用 dart pub deps 建立專案的依賴圖。最好自下而上地遷移套件;從依賴樹中的葉子開始,然後向上迭代到根。但是,如果您的專案具有依賴循環,這可能是不可能的,而且不遵循此順序也沒關係。

使用 遷移工具 遷移函式庫(或一組函式庫):

  1. 透過執行 dart migrate --skip-import-check 啟動互動式遷移工具。您可能希望 cd 到包含所選函式庫的目錄,以便在樹中更容易導航。
  2. 透過取消選取左側面板中檔案視圖樹的根來取消選取所有內容。(如有興趣,請投票支持新增 取消選取所有 按鈕。)
  3. 使用 Control+F 找到您要遷移的檔案。
  4. 選取檔案,然後點擊 應用遷移。您可以透過兩種方式進行調整:(1) 在應用遷移之前使用註釋來調整工具的選擇,或 (2) 在應用遷移之後使用 IDE 來評估欄位、參數和變數的可空性。
  5. 在 IDE 中打開套件。修復錯誤,並在檔案中搜尋工具可能不準確的情況(請參見下面的潛在問題列表)。進行更正並使用 lint 警告以互動方式清理上游和下游程式碼。

您將無法修復兩個 lint 錯誤:

  1. import_of_legacy_library_into_null_safe(在已遷移的函式庫中)
  2. avoid_redundant_argument_values(在 legacy 函式庫中)

現在,使用註釋停用這些錯誤。您將在遷移完成後清理這些錯誤。

需要注意的潛在工具不準確性:

  1. 加入的類型 dynamicnum。您很可能知道應該使用哪種特定類型來代替。
  2. 在大多數情況下,bool? 可以透過預設值變為 bool
  3. 類型轉換(搜尋 as)可能意味著該工具沒有加入泛型類型參數。加入之後,lint 會指示轉換已變得不必要,可以移除。
  4. 在某些情況下,該工具會使泛型參數上的界限可空,而最好將其設為不可空(搜尋 ?>?,)。
  5. 該工具可能會使某些內容可空,而使用 latelate final 可以更好地表達,或者可以重構以允許在建構函式的初始化列表中進行初始化。(如有興趣,請投票支持新增 lint。)
  6. 使用空斷言運算子 ! 而不先檢查空值可能意味著變數或參數實際上應該是非空的。(如有興趣,請投票支持新增 lint。)
  7. 該工具以 collection as Iterable<TheType> 的形式為集合加入轉換。有時,此變更只是使已經隱式的轉換變得明確。但是,在其他情況下,由於泛型引數的可空性不匹配,這些轉換可能會引入 執行時錯誤。如有疑問,請考慮將轉換替換為每個元素的顯式轉換(例如,collection.cast<TheType>()),或考慮使用 package:collection 中的 whereNotNull 擴展方法
  8. 如果變數、欄位或參數是可空的,但可空性僅在測試中使用,則可能應該重構程式碼以移除該標識符的可空性。

(感謝 Kenzie Davisson 幫助我識別出這些情況。)

步驟 3:清理

遷移所有函式庫後,請執行一些最終清理:

  1. 清理禁用 lint 的註釋。
  2. 將剩餘的依賴項升級到空安全版本。
  3. 確保您的應用程式中沒有剩餘的 //@dart = 2.9 註釋。此時,啟動應用程式時,您應該在控制台中看到「以健全的空安全模式運行」。如果您沒有看到此訊息,則可能是您的函式庫尚未遷移(搜尋 // @dart = 2.9),或者依賴項尚未遷移。
  4. 確保應用程式仍然可以正常運行,並且測試通過。由於健全模式啟用了更強的執行時保證,因此當您啟用健全空安全時,您可能會看到新的執行時錯誤,您需要修復這些錯誤(儘管不太可能)。通常這是將可空集合(例如 List<int?>)轉換為不可空集合類型(例如 List<int>)的結果。

祝您遷移順利!


大型 Dart 專案的漸進式空安全遷移 最初發佈在 Dart 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

【文章內容使用 Gemini 1.5 Pro 自動翻譯產生】

託管私有的 Dart 套件庫

我們最近發布的 Dart 2.15 版本增加了對私有套件庫的支援。套件庫是一個託管 Dart 套件的伺服器,供 dart pub 客戶端使用。這篇文章討論了如何將私有套件庫與 pub.dev 一起使用,並利用 Dart 2.15 中引入的新的權杖驗證機制。

此功能已被 CloudsmithJFrog Artifactory 採用,它們提供自定義套件庫作為服務:

Cloudsmith 和 JFrog Artifactory 現在都提供私有 Dart 儲存庫。

為什麼要使用自定義套件庫?

預設套件庫 pub.dev 由 Dart 團隊運營。它促進了 Dart 套件的發布以供公開使用,並允許任何 Dart 開發人員只需將套件的名稱添加到他們的 pubspec 檔案中即可使用這些套件。這使得活躍的生態系統可以建立豐富的 Dart 套件集合。但是,在以下情況下,自定義套件庫可能很有用:

  1. 在組織內共享私有套件。這可能是一個希望在其成員之間共享內部專有套件,而不是與公眾共享的組織。
  2. 在企業環境中嚴格控制依賴項。一些公司希望明確地為批准使用的特定 套件版本 建立允許清單。這可能是為了執行程式碼審查策略或許可證合規性。
  3. 沒有公共網際網路存取的 sécurisé 環境。一些組織在一個監管環境中運作,在該環境中不允許連接到公共網際網路,進而也不允許連接到 pub.dev。這通常適用於政府機構/承包商和一些銀行服務提供商。

只需要共享一些專有套件的組織(情況 1)可能會使用 git 依賴項。這是一個強大的機制,因為 dart pub 客戶端命令會調用 git 客戶端來複製 git 依賴項——透過這種方式,您可以使用 SSH 金鑰驗證複製依賴項,並使用 GitHub/GitLab 團隊管理權限。由於 GitHub 支援使用 Yubikey 的 SSH,此設定在某些情況下效果很好。

但是,在版本解決方面,dart pub 中的 git 依賴項有一些限制。當使用 git 依賴項時,dart pub 只會複製 pubspec.yaml 中指定的標籤/分支/引用,因為沒有嘗試多個版本依賴項的機制。因此,使用私有自定義套件庫可能很有吸引力,因為自定義套件庫可以向 dart pub 客戶端提供版本清單,允許 版本解決器 選擇相容的版本並避免衝突。它還可以輕鬆地使用 dart pub outdateddart pub upgrade --major-versions 升級私有和公共依賴項。

Git 依賴項不支援尋求 更嚴格的依賴項控制(情況 2)或使用 沒有網際網路存取的 sécurisé 環境(情況 3)的組織,因為許多套件必須鏡像。在這些情況下,幾乎總是最好只有一個自定義套件庫鏡像 pub.dev 的允許清單子集。

使用自定義套件庫

從 Dart 2.15 開始,您可以使用 簡短形式的託管依賴項 語法依賴於來自自定義套件庫的套件:

1
2
3
4
5
6
dependencies:
foo:
hosted: https://dart-packages.example.com
version: ^1.4.0
environment:
sdk: >=2.15.0 <3.0.0

簡短形式的語法需要 SDK 約束 >=2.15.0,因為舊版本的 Dart SDK 不支援此語法。如果您不想擔心語法,也可以只使用 dart pub add 命令從自定義套件庫中添加依賴項:

1
2
3
4
$ dart pub add foo --hosted https://dart-packages.example.com
Resolving dependencies...
+ foo 1.4.0
Changed 1 dependency!

使用託管依賴項語法,可以將來自自定義套件庫的依賴項與來自官方套件庫的依賴項混合使用。以下範例依賴於來自 dart-packages.example.com 儲存庫的套件 foo 和來自 pub.dev 的套件 retry

1
2
3
4
5
6
7
dependencies:
retry: ^3.0.0
foo:
hosted: https://dart-packages.example.com
version: ^1.4.0
environment:
sdk: >=2.15.0 <3.0.0

當使用自定義套件庫共享私有套件時(情況 1),這很有用。但是對於 更嚴格的依賴項控制(情況 2)或在 沒有網際網路存取的 sécurisé 環境(情況 3)中工作,最好覆蓋預設套件庫。

覆蓋預設套件庫

預設情況下,dart pub get 會從 pub.dev 獲取依賴項,除非使用託管依賴項語法指定自定義套件庫。但是,可以使用環境變數 PUB_HOSTED_URL 覆蓋 預設套件庫。當鏡像 pub.dev 的子集時(情況 2 或 3),此方法特別有用,因為無需更新 pubspec.yaml 檔案以引用自定義套件庫 URL。例如,只需編寫以下內容即可:

1
2
3
dependencies:
retry: ^3.0.0
foo: ^1.0.0

如果套件 retryfoo 的允許清單版本被複製到自定義套件庫,並且環境變數 PUB_HOSTED_URL 指向自定義套件庫 URL,則 pub get 可以按如下方式工作:

1
2
3
4
5
6
$ export PUB_HOSTED_URL=https://dart-packages.example.com
$ dart pub get
Resolving dependencies...
+ retry 3.1.0
+ foo 1.4.0
Changed 2 dependencies!

當建置伺服器位於公司防火牆後面,並且不允許外部網路連線以避免當有人忘記設定 PUB_HOSTED_URL 時的意外注入攻擊時,這種方法效果最佳。同樣,建議在 pubspec.yaml 中設定 publish_to: <hosted-url>,以避免意外發布到 pub.dev(當未定義 PUB_HOSTED_URL 時)。

針對自定義套件庫進行驗證

大多數自定義套件庫可能是需要驗證的私有套件庫。Dart 2.15 引入了 dart pub token 命令來管理驗證權杖。對自定義套件庫的請求使用秘密權杖進行驗證。您可以從自定義套件庫獲取秘密權杖,並將其傳遞給 dart pub token add <hosted-url>,它會提示輸入權杖,如下所示:

1
2
3
$ dart pub token add https://dart-packages.example.com
Enter secret token: [輸入秘密權杖]
Requests to "dart-packages.example.com" will now be authenticated using the secret token.

從 CI 環境進行驗證

在 CI 中運行時,通常可以將 秘密儲存在環境變數中,雖然可以使用 echo $TOKEN | dart pub token add <hosted-url> 傳遞秘密,但也可以告訴 dart pub 在與特定自定義儲存庫通信時從環境變數中讀取秘密:

1
2
$ dart pub token add https://dart-packages.example.com --env-var MY_SECRET_TOKEN
Requests to "https://dart-packages.example.com" will now be authenticated using the secret token stored in the environment variable "MY_SECRET_TOKEN".

這可確保 dart pub 不會實際將秘密儲存在其設定檔中,而只是儲存它應該從環境變數 $MY_SECRET_TOKEN 中讀取秘密的事實。這允許在 CI 環境中操作時僅將秘密儲存在環境變數中,並降低了如果執行環境在 CI 作業之間共享時秘密意外洩露的風險。

發布到自定義套件庫

要將套件發布到自定義套件庫,您需要在 pubspec.yaml 中指定 publish_to: <hosted-url>,然後運行 dart pub publish。這使用與 dart pub get 使用的相同的權杖進行驗證。至少,您的 pubspec.yaml 檔案應如下所示:

1
2
3
4
5
6
7
name: mypkg
version: 1.0.0
publish_to: https://dart-packages.example.com
dependencies:
meta: ^1.7.0
environment:
sdk: >=2.15.0 <3.0.0

運行 dart pub publish 時,務必查看提供的資訊。在確認發布操作之前,您應始終執行以下操作:

  • 檢查套件將發布到的 URL。
  • 查看要包含在套件中的檔案清單。
  • 考慮套件驗證建議。例如:
1
2
3
4
5
6
7
8
9
10
11
$ dart pub publish
Publishing mypkg 1.0.0 to https://dart-packages.example.com
|-- CHANGELOG.md
|-- LICENSE
|-- README.md
|-- lib
| '-- mypkg.dart
'-- pubspec.yaml
Package validation found the following potential issue:
* It's strongly recommended to include a "homepage" or "repository" field in your pubspec.yaml
...

對於發布到自定義儲存庫,建議 可能不 重要,但提供套件的元資料通常很有用。在 pub.dev 上,具有正確元資料和文件的套件得分更高 pub 分數

可以透過使用環境變數 PUB_HOSTED_URL 覆蓋 預設套件庫 來發布到自定義儲存庫,但是,如果您這樣做,強烈建議您在 pubspec.yaml 檔案中指定 publish_to: <hosted-url>;這可以防止您意外地將專有套件發布到公共儲存庫。如果您不想將專有套件發布到 任何 套件儲存庫,請指定 publish_to: none 以防止意外發布。

取得自定義套件庫

如前所述,自定義套件庫可作為多個商業供應商提供的服務,從而減輕您託管和維護自己的自定義套件庫的負擔。

Cloudsmith 中的權杖驗證

自 2020 年以來,Cloudsmith 一直提供私有和公共 Dart 套件庫。Cloudsmith 最近宣布 支援其 Dart 套件庫產品的權杖驗證。有關更多資訊,請查看 Cloudsmith 文件

由 Cloudsmith 託管的私有 Dart 套件庫。

JFrog Artifactory 中的 Dart 支援

JFrog Artifactory 最近 宣布支援自定義 Dart 套件庫,包括支援分層儲存庫和從 pub.dev 上的公共套件庫鏡像套件。有關更多資訊,請查看 JFrog Artifactory 文件

由 JFrog 管理的自定義 Dart 套件庫。

結語

對於那些想要編寫自己的自定義套件庫的人,我們發布了一個關於 提供 Dart 套件庫的規範。它相當簡單,但如果您不清楚某些方面,或者您有任何改進建議,請隨時在 pub.dev 儲存庫 上提交問題。


託管私有 Dart 套件庫 最初發佈在 Medium 的 Dart 上,人們在那裡透過突出顯示和回應這個故事來繼續討論。

【文章內容使用 Gemini 1.5 Pro 自動產生】

在提交截止日期之前完成你的專案!

距離 Flutter Puzzle Hack 提交截止日期只剩下幾天了。我們對到目前為止看到的拼圖感到興奮,並且迫不及待地想看到更多!別忘了,獎品包括 4 台配備齊全的 MacBook、大量 Flutter 周邊商品以及超過 40 位獲獎者的現金,因此請務必提交您的作品,以爭取獲得這些很棒的獎品。

歡迎來到 Flutter 社群

隨著最終提交日期的迅速臨近,我們想藉此機會歡迎許多新開發人員加入 Flutter 社群。我們迫不及待地想看看你們會做出什麼,當然,從你們的 Flutter Puzzle Hack 提交開始!

宣布我們的評審

為了慶祝 Flutter Puzzle Hack 的最後一周,我們很高興能宣布我們的評審,包括許多自 Flutter 成立以來就一直幫助構建此框架的 Flutter 老將。提交拼圖 Hack 作品是一個絕佳的機會,可以讓您在世界上頂尖的 Flutter 專家評審您的作品。

  • Justin McCandless,Flutter 框架軟體工程師
  • Casey Hillers,Flutter 工程軟體工程師
  • Christian Padilla,Flutter 外掛軟體工程師
  • Devon Carew,Flutter 軟體工程師
  • Greg Spencer,Flutter 框架/桌面軟體工程師
  • Michael Goderbauer,Flutter 框架首席軟體工程師
  • Craig Labenz,Flutter 開發者關係工程師
  • Yusuf Mohsinally,Flutter 工程軟體工程師
  • Laura Willis,Flutter 和 Firebase 產品行銷主管
  • Jay Chang,Flutter 產品行銷經理
  • Kelvin Boateng,Flutter 產品行銷經理
  • Huan Lin,Flutter on iOS 軟體工程師
  • Eric Windmill,Firebase 和 Flutter 開發者關係工程師

告訴我們您何時提交

無論您還在構思您的想法,還是已經提交了您的應用程式,請在 Twitter 上使用標籤 #FlutterPuzzleHack 標記我們,我們一定會與 Flutter 社群分享您的作品。

例如,看看 Twitter 使用者 Roaa 正在為 這個 作品做些什麼:

仍然有時間!

如果您還在考慮開始提交,現在還不晚。查看 樣板應用程式部落格文章 解釋了應用程式的工作原理,然後前往 flutterhack.devpost.com 查看挑戰規則。


距離 Flutter Puzzle Hack 提交截止日期只剩下幾天了 + 宣布評審 最初發佈在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

http://creativecommons.org/licenses/by/4.0/

【文章內容使用 Gemini 1.5 Pro 自動翻譯產生】

快速修復分析問題

如果您像我一樣,太多的開發時間都花在修復分析器找到的問題(診斷)上。如果您曾經希望它可以更容易,那麼我有一些好消息要告訴您。分析器產生的許多診斷都可以使用快速修復自動修復。

快速修復 是一種自動編輯,旨在修復特定診斷報告的問題。在 Dart 診斷訊息 文章中,我們查看了以下程式碼:

更正訊息建議了兩種解決問題的方法:「嘗試使存取成為條件式(使用 ‘?.’)或向目標添加 null 檢查(’!’)。」

如果您點擊突出顯示的區域(帶有紅色波浪線的區域),您會在編輯器左側看到一個燈泡圖示。如果您將滑鼠懸停在它上面,則可以點擊以打開包含可用快速修復的選單。

選單中提供了兩種建議的更正。選擇其中一個會將更改應用於您的程式碼。例如,如果您選擇第一個修復,它會將程式碼更新為以下內容:

讓我們先快速了解一下如何在 IntelliJ IDEAVisual Studio Code 中應用修復,然後再看一個更強大的快速修復示例。

IntelliJ IDEA

編輯器中的上下文動作選單如下所示:

您可以透過從編輯器中的上下文選單中選擇「顯示上下文動作」或使用其鍵盤等效項(Windows 和 Linux 上為 Alt+Enter,macOS 上為 Option+Enter)來存取相同的列表。

當您將滑鼠懸停在突出顯示的區域上時,您也可以直接從懸停文字中調用這些修復。如果修復太多,則還有一個 更多動作 項目也會打開選單:

如果這還不夠,您還可以從 Dart 分析視圖中的上下文選單中調用可用的修復:

Visual Studio Code

編輯器中的程式碼動作選單如下所示:

前兩項是快速修復,其他項是重構。您可以透過使用其鍵盤等效項(Windows 和 Linux 上為 **Control+.**,MacOS 上為 **Command+.**)或從編輯器中的懸停文字中選擇 快速修復… 來存取相同的列表:

您也可以從「問題」面板中的上下文選單中調用它們:

另一個例子

雖然上面的修復可以節省您查找更正訊息然後手動進行編輯的時間和精力,但不可否認,添加單個字元並不是一個很大的時間節約。但是,某些修復可以提高生產力。請考慮以下程式碼:

診斷告訴您「await 表達式只能在異步函數中使用。」假設您不想使用同步 I/O,則更正方法是用 async 關鍵字標記函數的主體。這樣做會導致另一個錯誤,告訴您方法的返回類型需要是 Future,因此您最終還需要更新返回類型。

幸運的是,有一個針對原始問題的快速修復:

選擇此修復不僅會添加修飾符,還會更新返回類型,讓您一步即可解決問題:

總結

並非每個問題都可以自動修復,並且並非每個可以修復的問題都有快速修復。儘管如此,下次您需要修復診斷時,絕對值得檢查一下是否有可用的快速修復。如果您沒有看到應該有快速修復的診斷的修復,請透過 建立 dart-lang/sdk 問題 告知我們。


分析問題的快速修復 最初發佈在 Dart 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

【文章內容使用 Gemini 1.5 Pro 自動產生】

2021 年第四季使用者調查結果:關於空安全、生態系統、文字編輯和行動開發

去年 11 月,Flutter UX 團隊進行了第 15 次季度使用者調查。調查透過 Flutter 的 IDE 外掛、YouTube、Twitter 和網站宣布。在兩個星期內,我們收集了 10,105 份回覆,創下歷史新高,我們了解到 Flutter 開發人員對 Flutter 仍然感到滿意。對 Flutter 感到滿意的人的比例為 92%,自 2019 年第四季以來一直保持穩定。

透過調查,Flutter 團隊也更詳細地了解 Flutter 的優缺點,並據此設定未來任務的優先順序。在這次調查中,我們詢問了以下四個主題,以深入了解這些領域。

  • 空安全
  • 生態系統
  • 文字編輯
  • 行動開發

為了讓調查簡短,我們向不同的群組詢問了不同的問題,因此您可能沒有看到所有這四個主題。無論如何,我們從所有參與者那裡收到了有意義的、具有統計意義的回饋。作為一個開源專案,我們試圖盡可能透明地公開我們收集的數據,因此我們在此分享結果和我們的收穫。

Dart 空安全

Dart 空安全的穩定版本於 2021 年 3 月 發佈。這是該語言中最大的新增功能之一,我們提供了一個遷移工具和一個 指南 來幫助開發人員將現有程式碼遷移到空安全。我們想了解遷移的體驗對您來說如何,這樣我們就可以在未來嘗試進行類似語言變更時做得更好。

總體而言,過去 6 個月使用過 Dart 空安全的 89.5% 的人對此功能感到滿意。那些先前有空安全經驗的人(例如 Kotlin)更有可能對此功能感到滿意(+3 個百分點)。Dart 空安全最大的好處是「程式碼中的錯誤減少了」(79.4%),其次是「更容易理解的程式碼」(49.7%)。

79% 的使用者有 Dart 空安全的使用經驗,並且 90% 對此感到滿意
大多數使用者 (79%) 表示 Dart 空安全減少了他們程式碼中的錯誤

有趣的是,39.9% 的人表示他們的所有程式碼都從一開始就使用空安全。鑑於調查是在穩定版空安全推出後僅 8 個月實施的,因此調查顯示了 Flutter 和 Dart 的快速發展,吸引了新的開發人員。這個結果也顯示了,59% 遷移程式碼的人以某種方式使用了遷移工具(22.0%+19.6%+6.7%=22.0%)。

40% 的使用者從一開始就使用空安全,而 59% 的使用者將其程式碼遷移到空安全

總體而言,調查結果支持繼續發展 Dart 語言使其變得更好。我們將繼續改進並在過程中考慮您的體驗。請繼續提供您的回饋!

生態系統

隨著 Flutter 不斷成熟,其套件和外掛生態系統也得到了改善。這項改善包括來自社群的貢獻,以及 Flutter FavoritesPlus 外掛Weekly Package 等程式和促銷活動。如下所示,對生態系統的滿意度在過去 2 年中提高了 7 個百分點。

對 Flutter 套件和外掛生態系統的滿意度在過去 2 年中提高了 7.5 個百分點

然而,我們仍然聽到您說,仍然有許多套件和外掛需要改進。為了更好地了解您的需求,我們詢問了「過去 3 個月是否有任何 Flutter 或 Dart 套件降低了您的應用程式開發生產力?」當 3,698 人中有 28.7% 對此問題回答「是」時,我們列出了 42 種不同的套件類型,並詢問了哪些套件降低了生產力。排名前 15 的套件如下。

雖然各種套件都導致開發人員生產力下降,但「Firebase」的排名第一,獲得了 22% 的投票。

Firebase 被 Flutter 使用者廣泛使用,這導致了相對較多的投票(22.1%)。我們將繼續投入到 Firebase 外掛(「FlutterFire」外掛)中。例如,去年 12 月,我們 發佈了 FlutterFire 外掛的穩定版本 並對其進行了標準化。這意味著所有 FlutterFire 外掛現在都使用相同底層版本的 SDK,開發人員在混合和匹配外掛時不會遇到版本不兼容問題。我們計劃監控此情況,並希望在下次詢問這個問題時看到 Firebase 變成開發人員更有效的服務。

上面圖表中另一個值得注意的是,42 個常見項目無法涵蓋所有需求,而 19.2% 的人選擇指定降低生產力的「其他」類型的套件和外掛。這突出了我們只是一個社群才能解決的各種需求。

對於這些套件,最大的挑戰是功能完整性——23.1% 的人表示套件的功能不完整,因此他們必須使用多個套件才能實現類似功能,或者無法滿足他們的需求。

套件的功能完整性是導致開發人員生產力下降的最主要因素

Flutter 團隊一直在努力改進我們第一方外掛的開發過程,使其更容易維護和改進。例如,webview_flutter 3.0 最近發佈,以解決許多頂級功能需求,我們將繼續投資於解決該外掛和其他外掛中投票數最高的議題。

即使我們自己繼續投入到 Flutter 和 Dart 團隊擁有的 數百個套件 這些都是 Flutter 社群可以發揮關鍵作用的領域。當我們都投入套件開發時,我們都會受益!

文字編輯

Flutter 提供了內建的 Widget,例如 TextField、TextFormField(以及它們的 Cupertino 對應物),以及各種套件,讓您可以在應用程式中加入文字編輯功能。當需要實作 live 篩選和格式化(例如,僅數字的電話號碼或價格輸入欄位)或豐富的文字編輯器(例如程式碼或數學公式編輯器)時,這會很快變得複雜。

從這次調查中,我們了解到大約 86.7% 的中級或高級經驗開發人員嘗試在他們的應用程式中加入文字編輯功能,而且對文字編輯功能的滿意度從單行 (82.3%) 和 live 篩選和格式化 (82.2%) 下降到多行 (69.6%) 和豐富文字編輯器 (66.6%)。

專家往往在將文字編輯功能加入應用程式方面擁有更多經驗

根據這個回饋,核心框架團隊計劃建立穩固的基本豐富文字編輯功能和 API 來支援套件。此外,團隊計劃更好地宣傳現有功能並建立更多範例。同時,您可以探索關於文字編輯變更的 設計文件 以查找有用的文件,以及 這個 GitHub 議題,以了解進度。這項工作已經進行得很好,一些低階 API 現在已經在 master channel 中。

我們也聽說了與支援不同語言相關的挑戰。例如,我們清楚地聽到 RTL 和雙向文字(例如阿拉伯語)無法正常運作。雖然沒有書面路線圖,但我們計劃很快大力推動更好地支援 RTL 和雙向文字編輯。

行動開發

由於行動平台(iOS 和 Android)是 Flutter 最初正式支援的平台,因此大多數人都有在過去 6 個月內開發 iOS 或 Android 應用程式的經驗。團隊想更好地了解特定於平台的問題,例如與除錯和發佈相關的挑戰,以便團隊能夠更好地為其工程工作設定優先順序。

過去 6 個月,分別有 72% 和 91% 的開發人員為 iOS 和 Android 開發應用程式

在除錯方面,在兩個平台上,使用者在加入或升級套件或外掛時,經常需要處理特定於平台的問題。雖然在許多情況下除錯 Android 問題並不常見,但值得注意的是,在 Android 上除錯以優化效能比 iOS 更常見。

在加入或升級套件或外掛時,除錯平台問題的頻率更高

我們還了解到,在發佈應用程式時,處理 Xcode(iOS)和 Gradle(Android)是最常見的問題,這與我們的直覺一致。我們已經讓 Flutter CLI 顯示針對常見 Gradle 錯誤的使用者友善錯誤訊息,這個功能已在最新更新 Flutter 2.10 中發佈。

我們將繼續改進這些構建系統錯誤的呈現方式,使其更容易理解和操作。對於 iOS,我們將在未來的版本 (相關議題在此) 中加入 flutter build ipa 功能,使發佈變得更容易。更多 Xcode 設定也會自動填充到新專案 (議題) 中。對於 Android,我們正在開發一個自動遷移工具,它將有助於查找 Gradle 配置檔案中的細微差異。

超過 36% 的開發人員在發佈應用程式時處理 Xcode (iOS) 和 Gradle (Android) 問題

接下來是什麼?

開發人員越來越多地將 Flutter 作為他們主要工作的一部分使用。Flutter 團隊將繼續聆聽並使用您的回饋來塑造我們的技術。如果您有任何緊急問題,請在 GitHub 上提交議題。

使用 Flutter 作為主要工作的開發人員比例一直在增加

Flutter 季度使用者調查將繼續尋找重要問題的答案。您也可以在 GitHub 上發佈您的研究想法。請留意下一次調查。此外,請考慮透過 註冊參加未來的 UX 研究 來參與其他研究。

再次感謝所有提供回饋的人!


2021 年第四季使用者調查結果:關於空安全、生態系統、文字編輯和行動開發 最初發佈在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

【文章內容使用 Gemini 1.5 Pro 自動產生】

Flutter 在 2022 年的策略和路線圖

Illustration of the Flutter and Dart mascot, Dash, looking across a cityscape, representing the future for our products.

Flutter 在我們建立成長和動能的過程中所關注的領域

每年,我們和其他 Google 的大型團隊一樣,都會進行規劃過程,以設定我們在未來一年的目標和重點領域。通常,產品團隊會嚴格保護這些文件,因為它們可能包含商業敏感資訊,或與競爭優勢領域相關。然而,作為一個開源專案,我們認為透明度是一種美德:它可以讓人們更信賴我們的未來和方向,並讓其他人更清楚地了解他們的投資如何與我們的投資相連。

因此,今天我們首次與整個社群分享我們的 年度策略文件。在這個文件中,我們表達了我們的使命,分享了一些指導原則,並描述了我們計劃在未來一年進行的主要投資。出於必要,我們做了一些小幅度修改(例如,商業敏感資料或對未宣布產品的參考),但我們相信這提供了對我們計劃良好的概述。這個策略文件應該與我們 wiki 上的 工程路線圖 一起閱讀,後者提供了有關我們正在開發的功能的更多細節。

關於以上句子中使用「我們」這個詞的一個重要說明,這可能被理解為「那些 Google 付錢讓他們在 Flutter 上工作的人」。Flutter 是 Google 內外許多貢獻者的成果。雖然 Google 是最大的贊助商,以付費貢獻者的數量衡量,但它不是唯一的貢獻者。在過去的一年裡,數千名個人為該專案貢獻了他們的智慧財產和勞動力,從個人到 Canonical、Microsoft、ByteDance 和阿里巴巴等大型企業。

因此,雖然策略文件描述了 Google 的投資並分享了這些決策背後的理由,但它並不打算限制他人對 Flutter 的貢獻方式。我們希望我們的作品能夠很好地滿足整個社群的需求,但我們預計分享這個文件的一個好處是,其他人將看到他們自己的投資機會,無論是建立在 Google 計劃貢獻的作品之上,還是填補我們沒有優先考慮的領域。

這方面的例子包括 Sony 在 嵌入式 Linux 上的工作;Toyota 和其他汽車公司在 汽車級 Linux 中使用 Flutter 的投資,以及三星和其他公司將 Flutter 移植到 Tizen 的工作。雖然這些工作都沒有列在我們的策略文件中,但它仍然是 Flutter 專案的一部分,就像 Google 貢獻的任何程式碼一樣。當然,還有數萬個建立在框架之上的套件,其中絕大多數來自 Google 之外的開發人員。

最後一個免責聲明:我們的策略可能會隨著時間推移而演變,因為我們將繼續與社群互動,以及商業優先順序和策略的變化。因此,這裡所述的任何內容都不要被視為具有約束力的承諾,即使我們計劃將其作為我們的指南。


Flutter 在 2022 年:策略和路線圖 最初發佈在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

http://creativecommons.org/licenses/by/4.0/

【文章內容使用 Gemini 1.5 Pro 自動產生】

宣布 Flutter 2.10:穩定版 Windows、效能提升、Material 3 更新等等!

我簡直不敢相信又到了 Flutter 穩定版本發佈的時候!大家好,歡迎來到 Flutter 2.10。距離我們上次發佈版本還不到兩個月,但即使在那段時間裡,我們也收到了來自全球 155 位貢獻者的 1,843 個已解決的議題和 1,525 個已合併的 PR。感謝大家辛勤付出,特別是在 2021 年的假期期間。

這個版本有許多令人興奮的更新,包括 Flutter 對 Windows 支援的重大進展、幾個重要的效能提升、框架中對圖示和顏色的新支援,以及一些工具的改進。此外,我們還有一些關於移除 dev 頻道的更新、對舊版 iOS 的支援減少,以及一些重大變化的簡短清單。讓我們開始吧!

Windows 上的生產應用程式準備就緒

首先,Flutter 2.10 版本帶來了 Windows 支援的穩定版本。您不再需要切換旗標來獲得在 Flutter 的 stable 頻道上生成 Windows 應用程式的功能 - 現在這個功能預設提供!

當然,我們做的不僅僅是切換旗標。這個版本包括對文字處理、鍵盤處理和鍵盤快捷鍵的廣泛改進,以及與 Windows 的直接整合,支援命令列參數、全球化文字輸入和無障礙功能。

關於 Windows 穩定版發佈的更多資訊,請參閱 宣布 Flutter for Windows 部落格文章,這篇文章描述了 Flutter 在 Windows 上的架構,它允許深度整合,並讓您了解有多少 Flutter 套件和插件已經支援 Windows。您也可以看到我們的工具和應用程式合作夥伴使用 Flutter 在 Windows 上做的一些例子!

效能提升

此版本包含 Flutter 的初始支援,即由 Flutter 社群成員 knopp 提供的 髒污區域管理。他為 iOS/Metal 上單個髒污區域啟用了局部重新繪製。此變更將幾個基準測試的第 90 個和第 99 個百分位數的柵格化時間減少了數量級,並且將這些基準測試上的 GPU 使用率從 90% 以上降至 10% 以下。

我們預計在未來的版本中將局部重新繪製的好處帶到 其他平台

在 Flutter 2.8 版本中,我們 推出了我們自己的內部圖片記錄格式。現在在 Flutter 2.10 中,我們已經開始利用它建立優化。例如,**透明度層的常見用例現在 實現得更加高效**。即使在最壞的情況下,基準測試中的畫面柵格化時間也降至之前值的 1/3 以下。

我們預計這種優化將在我們繼續開發圖片記錄格式時擴展到更多案例。

在 Profile 和 Release 模式下,Dart 程式碼會提前編譯成原生機器碼。此程式碼效率高且體積小的關鍵是全程式碼類型流分析,它可以解鎖許多編譯器優化和積極的樹狀搖動。然而,由於類型流分析必須涵蓋整個程式碼,因此它可能有點昂貴。這個版本包含 類型流分析的更快速實作。基準測試中 Flutter 應用程式的整體構建時間下降了約 10%。

與往常一樣,效能提升、減少記憶體使用和降低延遲是 Flutter 團隊的優先順序。期待在未來的版本中看到更多改進。

iOS 更新

除了效能提升,我們還新增了一些平台特定的功能和增強功能。一個新的增強功能是來自 luckysmgiOS 上更平滑的鍵盤動畫,它會自動提供給您的應用程式,您無需做任何事情。

我們還透過修復一些 邊緣 案例崩潰 來提高 iOS 相機插件的穩定性。

最後,64 位 iOS 架構獲得了一個新的功能來減少記憶體使用:壓縮 **指標****。

一個 64 位架構將指標表示為一個 8 位元組的資料結構。當您有很多物件時,指標本身佔用的空間會增加應用程式的整體記憶體使用量,特別是如果您有更大、更複雜的應用程式,這些應用程式具有更多 GC 抖動。但是,您的 iOS 應用程式不太可能擁有足夠的物件來需要大量使用 32 位地址空間(20 億個物件),更不用說 64 位地址空間的巨大空間(90 億億個物件)。

壓縮指標在 Dart 2.15 中提供,在此版本中,我們使用它們來減少 64 位 iOS 應用程式的記憶體使用量。您可以 查看 Dart 2.15 部落格文章以獲取詳細資訊

當您閱讀 Dart 部落格文章時,別忘了 查看 Dart 2.16 宣布,其中包含關於使用套件平台標記支援 Flutter for Windows 以及在 pub.dev 上推出新的搜尋體驗的更新。

Android 更新

這個版本還包含許多針對 Android 的改進。預設情況下,當您建立新的應用程式時,Flutter 預設支援最新版本的 Android,版本 12(API 級別 31)。此外,在此版本中,**我們已 **自動啟用 multidex 支援**。如果您的應用程式支援 Android SDK 版本低於 21,並且超過 64K 方法限制,只需將 --multidex 旗標傳遞給 flutter build appbundleflutter build apk,您的應用程式就會支援 multidex。

最後但並非最不重要的一點是,我們聽取了您的反饋意見,認為 Gradle 錯誤訊息會令人望而生畏。因此,Flutter 工具現在會建議如何解決常見問題的步驟 。例如,如果您為應用程式加入一個 Plugin,它需要您提高最低支援的 Android SDK 版本,您現在會在日誌中看到一個「Flutter Fix」建議。

我們將繼續為常見的錯誤訊息新增更多建議,並且樂於收到您對其他錯誤訊息的回饋,這些錯誤訊息也可能需要這種處理方法。

Web 更新

這個版本還包含一些針對 Web 的改進。例如,在之前的版本中,當捲軸到 Web 上多行 TextField 的邊緣時,它不會正確捲軸。這個版本引入了 文字選取的邊緣捲軸:當選取範圍移動到文字欄位之外時,欄位會捲軸以顯示捲軸範圍。這種新的行為適用於 Web 和桌面應用程式。

此外,這個版本的 Flutter 包含了另一個針對 Web 的顯著改進。我們一直在尋找方法來減少 Flutter 對 Web 的對映開銷。在之前的版本中,每次我們想要將原生 HTML Widget 加入到 Flutter 應用程式時,我們都需要一個覆蓋層作為我們針對 Web 的平台視圖支援的一部分。這些覆蓋層中的每一個都允許自訂繪製,但會造成一定程度的開銷。如果您的應用程式中有大量的原生 HTML Widget,例如連結,這些開銷會加起來。在此版本中,我們為 Web 建立了一個新的「非繪製平台視圖」,基本上消除了這種開銷。我們已經 連結 Widget 中利用了這種優化,這意味著如果您的 Flutter Web 應用程式中有許多連結,它們將不再會造成任何顯著的開銷。我們將隨著時間推移將這種優化應用於其他 Widget。

Material 3

此版本是過渡到 Material 3 的開始,其中包括 從單個種子顏色生成整個顏色配置 的功能。

使用任何顏色,您可以構造一個新的 ColorScheme 類型的實例:

ThemeData 工廠建構函式中還有一個新的 colorSchemeSeed 參數,允許您生成主題的顏色配置:

此外,此版本還包含 ThemeData.useMaterial3 旗標,它將組件切換到新的 Material 3 外觀

最後但並非最不重要的一點是,**我們已新增 1,028 個新的 Material 圖示**。

1,028 個新的 Material 圖示的一點小樣本

可以在 跟踪我們 Material 3 工作的議題 中找到更新;歡迎您提供您的回饋。

整合測試改進

在 2020 年 12 月,我們宣布了一種使用 integration_test 套件 進行端到端測試的新方法。這個新的套件取代了 flutter_driver 套件,成為進行整合測試的推薦方法,它提供了一些新功能,例如 Firebase Test Lab 支援以及對 Web 和桌面的支援。

從那時起,我們在整合測試方面又進行了進一步的改進,包括 integration_test 套件捆綁到 Flutter SDK 本身,使其更容易與您的應用程式整合。還有一個 **新的 遷移指南,如果您要將現有的 flutter_driver 測試遷移到 integration_test**。

`flutter_driver` 到 `integration_test` 遷移指南中的範例

幾個 現有的 文件範例codelab 也已更新為 integration_test。要開始使用,請將您的瀏覽器指向 flutter.dev 上的 測試 Flutter 應用程式 頁面。如果您還沒有在 Flutter 應用程式中使用 integration_test,現在是開始的時候了!

Flutter DevTools

我們也在這個版本中為 Flutter DevTools 做了一些工作,包括如果您從命令列使用 DevTools 的一個易用性功能。您現在不再需要使用 pub global activate 來下載和執行最新版本,而是可以 直接使用 dart devtools 並獲得與您正在使用的 Flutter 版本保持一致的版本。

我們還進行了一些 許多 可用性 更新,包括 改進了在除錯器變數窗格中檢視大型列表和映射的支援(感謝 elliette)。

最後,我們即將發佈 年度 DevTools 調查!請提供您的回饋,幫助我們改進您的開發體驗。

這個調查提示將在 2 月中旬左右直接顯示在 DevTools 中。謝謝!

VSCode 改進

Flutter 的 Visual Studio Code 擴展也獲得了一些增強功能,包括 在程式碼中更多位置顯示顏色預覽一個可以為您更新程式碼的顏色選擇器

此外,如果您想成為 VSCode 的 Dart 和 Flutter 擴展的預發行版本的測試人員,您可以在 [擴展設定中切換到預發行版本](https://github.com/Dart-Code/Dart-Code/issues/
3729)。

您可以在 flutter-announce 郵件列表 上的 這篇文章 中閱讀有關此更新的詳細資訊以及更多內容。

移除 dev 頻道

Flutter 2.8 版本 中,我們宣布我們正在進行 移除 dev 頻道 的工作,簡化您的選擇,並減少工程開銷。在此版本中,我們已完成這項工作,包括:

  • 更新了 Flutter 工具,以幫助開發人員從 dev 頻道遷移
  • 更新了 Wiki 以反映更新後的客戶承諾
  • 更新了棄用政策
  • 從 DartPad、預提交測試和網站中移除 dev 頻道支援

dev 頻道現在已經被清除了。如果您發現我們遺漏了某個地方,請 告訴我們

停止支援 iOS 9.3.6

由於使用率下降以及在實驗室中維護目標設備的難度越來越大,我們正在 停止支援 iOS 9.3.6,將其從「支援」層級移動到「最佳努力」層級。這意味著對 iOS 9.3.6 和 32 位 iOS 設備的支援將僅透過編碼實務、臨時和社群測試來維護。

在 2022 年第三季度的穩定版本中,我們預計將從 Flutter 穩定版本中刪除對 32 位 iOS 設備和 iOS 版本 9 和 10 的支援。這意味著從那時起針對穩定版 Flutter SDK 構建的應用程式將不再能在 32 位 iOS 設備上運行,Flutter 支援的最低 iOS 版本將升級到 iOS 11。

重大變更

我們還努力讓每個版本中都 只有少數重大變更,而這個版本雖然還沒有完全達到零,但我們會繼續努力!

如果您仍然使用這些 API,您可以 閱讀 flutter.dev 上的遷移指南。與往常一樣,非常感謝社群為 貢獻測試,這些測試幫助我們識別出這些重大變更。

總結

來自 Google Flutter 團隊的所有人,我們想說 - 謝謝。謝謝您成為社群的一部分,幫助 Flutter 成為最受歡迎的跨平台 UI 工具包,這一點得到了 Statista 和 SlashData 等分析師的認可。對 Windows 的穩定支援只是我們忙碌的一年的開始,我們迫不及待地想看到我們一起構築的每一樣東西!


Flutter 2.10 的新功能 最初發佈在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

【文章內容使用 Gemini 1.5 Pro 自動產生】

宣布 Flutter for Windows

自我們推出 Flutter 以來,我們一直專注於提供一個跨平台解決方案,用於構建精美的自定義應用程式,這些應用程式被編譯為機器碼,並充分利用您設備的底層圖形硬體。今天,隨著 Windows 作為應用程式目標的首次生產版本支援的發布,我們擴展了這個願景,使 Windows 開發人員能夠從移動開發人員一直以來享有的相同生產力和功能中受益。

An image of a laptop with two light blue birds, representing Dash, the mascot of Flutter and Dart, hovering over the keyboard. The text in the image says, “Flutter + Windows”.

我們對 Flutter 的目標是為您提供構建出色體驗所需的工具,無論您是在為哪個作業系統構建應用程式。因此,我們希望將相同的核心框架和工具帶到您想繪製像素的所有地方。Flutter 允許您精雕細琢 **精美** 的體驗,讓您的品牌和設計成為焦點。Flutter **快速**,直接編譯為機器碼;通過狀態熱重載支援,您可以獲得互動式開發環境的 **生產力**,讓您可以在應用程式運行時進行更改,並立即看到結果。Flutter **開源**,擁有數千名貢獻者為核心框架添加內容,並用套件生態系統擴展它。

幾乎有 50 萬個應用程式使用 Flutter……

到目前為止,我們已經看到了超出預期的發展勢頭,現在已經發布了近 50 萬個使用 Flutter 的應用程式,包括來自 Betterment、BMW 和 ByteDance 等公司的重大應用程式,以及來自 Google 的 30 個團隊的應用程式。在 2021 年,Flutter 根據 Statista 和 SlashData 等分析師的衡量標準,成為最受歡迎的跨平台 UI 工具包:

Extracts from studies by Statista (“Flutter is the most popular cross-platform mobile framework used by global developers… 42% of software developers used Flutter”), SlashData (“The most popular cross-platform frameworks for development include Google’s Flutter (44%)”), JetBrains (“The popularity of Flutter continues to grow. This year it has surpassed React Native to become the most popular…”) and StackOverflow (“Flutter is the #2 loved framework”).

我們自己的數據證實了這一點,在 2021 年的所有四個季度調查中,有 92% 的 Flutter 開發人員對我們的工具表示滿意。 (對於其他 8% 的用戶,我們正在傾聽您的反饋,並希望您也感到滿意!)

一個常見的要求是 Windows 支援。

今天,我們很高興宣布 Flutter 在穩定版本中完整支援 Windows 應用程式。

Windows 和 Flutter

幾年前,我們為 Flutter 構建了一個雄心勃勃的願景,從 iOS 和 Android 上的行動應用程式擴展到其他平台,包括 Web 和 *桌面*。

Flutter 的核心跨越平台:從可移植的硬體加速 Skia 圖形引擎到 Flutter 渲染系統;核心原語,如動畫、主題、文字輸入和國際化;以及 Flutter 提供的數百個 Widget。

但是,桌面應用程式不僅僅是在更大螢幕上運行的行動應用程式。它們是為不同的輸入設備(例如鍵盤和滑鼠)而設計的。它們具有可調整大小的視窗,通常在寬螢幕顯示器上運行。對於關鍵事項(如輔助功能、輸入法編輯器和視覺樣式)存在不同的慣例。它們與底層作業系統中的不同 API 整合:桌面應用程式支援從檔案系統選擇器到設備硬體到 Windows 登錄等數據存儲的所有內容。

因此,雖然我們將 Flutter *帶到* Windows,但我們也為 Windows *量身定制* 了它。

與我們對 Android 和 iOS 的支援一樣,Flutter 的 Windows 實作結合了 Dart 框架和 C++ 引擎。Windows 和 Flutter 通過一個嵌入層進行通訊,該嵌入層託管 Flutter 引擎,並負責轉換和分派 Windows 消息。Flutter 與 Windows 配合將您的 UI 繪製到螢幕上,處理視窗調整大小和 DPI 變化等事件,並使用現有的 Windows 模式進行國際化,例如輸入法編輯器。

An architectural diagram showing the Flutter architecture: at the top is the Flutter framework, built in Dart, which comprises building blocks like Material, the widgets system, rendering objects, animation, gestures, and painting primitives. Below that is the Flutter engine, written in C++, as well as the Skia and text rendering libraries; lastly, the Windows embedder which interoperates with the underlying operating system and passes Win32 messages to the engine.
在 Windows 上,Flutter 使用完全相同的 Dart 程式碼,但利用了原生 Windows API。

您的應用程式可以使用 Flutter 框架的每個部分,在 Windows 上,它也可以直接通過 Dart 的 C 互操作層或使用用 C++ 編寫的平台插件與 Win32、COM 和 Windows 執行時 API 通話。我們還適應了一些常見的 Plugin,以包含 Windows 支援,包括 camera、file_picker 和 shared_preferences。更重要的是,社群已經為各種其他套件添加了 Windows 支援,涵蓋從 Windows 工作列整合到串列埠存取的所有內容。

A list of some Windows packages, including USB support, maps, web, serial port, file selection, window management, TensorFlow, credential management, battery, WMI, printer, screen capture and network connectivity.
已經有數百個套件已適應以支援為 Windows 構建的 Flutter 應用程式。

為了獲得完全自定義的 Windows UI,您還可以利用 `fluent_ui` 和 `flutter_acrylic` 等套件來建立一個精美地表達 Microsoft Fluent 設計系統的應用程式。使用 `msix` 工具,您可以將應用程式包裝在安裝程式中,可以上傳到 Windows 上的 Microsoft Store。

總之,這促進了應用程式的創建,這些應用程式在 Windows 上看起來很棒,在 Windows 上運行很快,並且仍然可以傳輸到其他桌面或行動設備以及 Web。以下是我們到目前為止看到的一些早期範例:

一些使用 Flutter 構建的 Windows 應用程式的早期社群範例,包括 Harmonoid 和 Rows。

Microsoft 和 Flutter

我們詢問 Windows 團隊是否願意分享一些關於 Flutter 支援的意見。以下是 Microsoft Windows 開發者平台公司副總裁 Kevin Gallo 的說法:

“我們很高興看到 Flutter 添加了對創建 Windows 應用程式的支援。Windows 是一個開放平台,我們歡迎所有開發人員。我們很興奮看到 Flutter 開發人員將他們的經驗帶到 Windows,並發布到 Microsoft Store。Flutter 對 Windows 的支援是社群的一大步,我們迫不及待地想看看您將為 Windows 帶來什麼!”

事實上,Microsoft 的幾個團隊都為今天的公告做出了貢獻。特別是,我們想感謝 Fluent 設計團隊為 Windows 上的 Flutter 應用程式貢獻圖標。他們的 `fluentui_system_icons` 套件已獲得 Flutter Favorite 狀態,以證明其品質。

我們還對 Microsoft 在 Windows 輔助功能方面進行的投資印象深刻,我們感謝該團隊的幫助,確保 Flutter 從一開始就支援螢幕閱讀器。將輔助功能視為利基需求是一個錯誤。正如 Microsoft 包容性設計工具包中的這張圖所示,我們都有理由關心提供適合不同永久性、暫時性或情境性需求的體驗。

A diagram showing how accessibility aids can be of use to a wide audience, in three categories: permanent impairments such as blindness or deafness; temporary conditions such as an arm injury or cataract; or situational needs such as a new parent who is holding a baby with one arm, or a driver who is unable to look at a screen.

下面的視頻演示了 Flutter 如何與 Windows Narrator 整合。出於這個視頻的目的,我們故意模糊了螢幕,讓您了解這項功能對需要它的人來說是多麼有價值。

Windows 開發工具的生態系統

我們的工具合作夥伴也正在添加對 Windows 的支援。以下是一些重點:

  • FlutterFlow,低程式碼 Flutter 應用程式設計工具,今天宣布支援 Windows,以及幫助 Flutter 開發人員構建針對桌面使用量身定制的應用程式的功能。
  • Realm 是一個超快速的本地數據存儲。今天發布的最新版本現在支援使用 Flutter 構建 Windows 應用程式,使用 Dart FFI 快速存取底層數據庫,從而為 iOS 和 Android 等行動平台提供現有的支援。
  • Nevercode 已更新其 Codemagic CI/CD 工具以支援 Windows,使您能夠在雲端測試和構建 Windows 應用程式,並自動將應用程式部署到 Microsoft Store。
  • Syncfusion 已更新其 Widget 套件,以充分利用 Windows。如果您訂閱其工具包,您將發現數據可視化組件,例如樹狀圖和圖表,豐富的數據網格 Widget,日曆,甚至支援 PDF 創建和 Excel 電子表格。
  • 最後,Rive 今天宣布即將推出的其熱門圖形工具套件的 Windows 版本,允許設計人員和開發人員創建互動式矢量動畫,這些動畫可以使用狀態機實時響應程式碼。其應用程式即將推出的 Windows 版本提供超快的效能和更低的內存占用率,並將很快在 Microsoft Store 上供下載。
A screenshot of Rive, a motion design tool that is written in Flutter and produces output that can be embedded into any Flutter app.
Rive,即將在 Windows 上的 Microsoft Store 上推出。

看到圍繞 Flutter 建立的成熟生態系統,我們感到非常興奮,我們鼓勵您在使用 Flutter 構建 Windows 應用程式時查看每一個合作夥伴。

Windows 支援在 Flutter 2.10 中推出

構建 Windows 應用程式的穩定、生產級品質支援作為 Flutter 2.10 的一部分提供,該版本今天發布。Flutter 2.10 還包含許多其他功能、效能改進和錯誤修復,這些內容在單獨的部落格文章中詳細介紹。

在接下來的幾個月裡,您將從我們那裡聽到更多關於完成對 macOS 和 Linux 的穩定支援的消息,為您的生產 Flutter 應用程式提供完整的桌面、Web 和行動平台。

同時,感謝您對 Flutter 的支援。我們很興奮看到您為 Windows 構建的內容!

An image of the Dart mascot, Dash. She is sitting behind a laptop computer with a Flutter logo. We can’t see it, but she’s looking at a Windows app built in Flutter!


宣布 Flutter for Windows 最初發佈在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

http://creativecommons.org/licenses/by/4.0/

【文章內容使用 Gemini 1.5 Pro 自動翻譯產生】

Dart 2.16:改進的工具和平台處理

今天,Dart SDK 2.16 版本正式推出。它沒有新的語言功能,但包含許多錯誤修復(包括一個安全漏洞的修復)、改進了對指定 Dart 套件支援平台的支援,以及全新的 pub.dev 搜尋體驗。

Dart 2.16

今天與 Flutter 2.10 一起推出的 Dart 2.16 SDK 繼續從傳統的 Dart CLI 工具(dartfmt、dartdoc 等)過渡到新的組合式 dart 開發者工具。新棄用的工具是 dartdoc(使用 dart doc)和 dartanalyzer(使用 dart analyze)。在 Dart 2.17 中,我們計劃完全移除 dartdocdartanalyzerpub 命令(在 Dart 2.15 中已棄用;使用 dart pubflutter pub)。有關詳細資訊,請參閱 issue #46100

2.16 版本還包括一個安全漏洞的修復和兩個小的重大變更:

  • dart:io 中的 HttpClient API 允許您為授權、www-authenticatecookiecookie2 設定選用標頭。在 Dart 2.16 之前的 SDK 中,重定向邏輯的實作存在一個漏洞,即當發生跨域重定向時,這些標頭(可能包含敏感資訊)會被傳遞。在 Dart 2.16 中,這些標頭會被丟棄。有關詳細資訊,請參閱 CVE-2022-0451
  • dart:io 中的 Directory.rename API 在 Windows 上的行為已變更:它不再刪除與目標名稱匹配的現有目錄(issue #47653)。
  • Platform.packageRootIsolate.packageRoot API(它們是 Dart 1.x 的遺留物,在 Dart 2.x 中不起作用)已被移除(issue #47769)。

若要查找有關 Dart 2.16 中變更的更多詳細資訊,請參閱 變更日誌

新增對宣告 pub.dev 套件平台支援的支援

Dart 的設計旨在實現可移植性,我們努力讓程式碼能夠在最多的平台上運行。但是,有時您可能會在 pub.dev 上建立和分享僅針對一個或幾個平台設計的套件。您可能有一個套件依賴於僅在特定作業系統上可用的 API,或者一個套件使用僅在原生平台上支援且在網頁上不支援的函式庫,例如 dart:ffi

透過 Dart 2.16,您現在可以在套件的 pubspec 中手動宣告支援的平台集。例如,如果您的套件僅支援 Windows 和 macOS,則其 pubspec.yaml 檔案可能如下所示:

1
2
3
4
5
6
7
8
name: mypackage
version: 1.0.0

platforms:
windows:
macos:

dependencies:

新的 platforms 標籤適用於您正在開發 Dart 套件,並且您想要宣告對與 pub.dev 自動偵測到的平台集不同的平台集的支援的情況。如果您正在開發和分享包含主機特定程式碼(例如,Kotlin 或 Swift)的 Flutter Plugin,則 Flutter Plugin 標籤 通常會指定支援的平台。

全新的 pub.dev 搜尋 UI

為了回應開發人員的要求,我們為在 pub.dev 上搜尋套件建立了更好的支援。今天推出的變更的主要目標是幫助您識別和搜尋支援的平台集。以下是全新搜尋體驗的視圖:

Pub.dev 搜尋介面,左側邊欄包含平台、SDK 和進階搜尋過濾器

新的搜尋 UI 在左側有一個搜尋過濾器側邊欄,您可以使用它來限制您的套件搜尋:

  • 平台: 選擇一個或多個平台,將搜尋結果縮小到僅支援所有選定平台的套件。
  • SDK: 選擇 Dart 或 Flutter,將結果限制為分別支援 Dart SDK 或 Flutter SDK 的套件。
  • 進階: 其他搜尋選項,例如過濾到 Flutter Favorite 套件。

空安全更新

自從我們上次談論空安全(一年前在 Dart 2.12 中推出的主要語言新增功能)以來,已經發佈了幾個版本。我們對 Dart 生態系統遷移套件以支援空安全的速度感到驚訝:截至今天,前 250 個套件中的 100% 以及前 1000 個套件中的 96% 都支援空安全!感謝所有為這一偉大成就做出貢獻的套件作者。

我們也看到應用程式遷移到健全的空安全(應用程式程式碼和所有套件依賴項都已遷移的狀態)方面取得了良好進展。根據我們的分析,Flutter 工具中的所有運行會話中有 71% 現在具有完全健全的空安全。如果您是應用程式開發人員並且尚未遷移,那麼現在是絕佳時機。

結語

我們希望您覺得新的 pub.dev 搜尋 UI 很有用,並且我們歡迎您提供任何 回饋。敬請期待下一個 Dart SDK 版本,計劃於 2022 年第二季度發佈。我們正在開發幾個 令人興奮的語言功能,我們希望在今年晚些時候發佈。


Dart 2.16:改進的工具和平台處理 最初發佈在 Dart 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

【文章內容使用 Gemini 1.5 Pro 自動產生】

您可能已經閱讀過 [Flutter 拼圖黑客挑戰](https://flutterhack.devpost.com/),並正在思考如何將您的創造力推向新的極限。我們在此提供有關樣本程式碼庫結構的更多資訊,並提供一些關於如何建立您的比賽提交的一些想法。

滑動拼圖架構

提供的原始碼實作了一個分層架構,使用 flutter_bloc 管理狀態。Bloc 處理從遊戲邏輯到主題的所有內容。所有狀態都以一致的方式管理;針對拼圖邏輯的任何更新,您只需要找到對應的 bloc 並更新它。重設和洗牌遊戲按鈕、計時器和倒計時都是獨立的 bloc,因此這些可能是您考慮實作創造性的其他地方:也許是沙漏作為計時器?或者是一個華麗的洗牌順序?

請注意,所有遊戲邏輯都包含在一個名為 PuzzleBloc 的單一 bloc 中。它將透過事件更新,例如點擊一個磁磚以移動拼圖磁磚的 TileTapped 事件,或使用 PuzzleReset 完全重設拼圖板。每次拼圖更新時,都會發出新的拼圖狀態。

class PuzzleBloc extends Bloc<PuzzleEvent, PuzzleState> {
PuzzleBloc(this._size, {this.random}) : super(const PuzzleState() {
on<PuzzleInitialized>(_onPuzzleInitialized);
on<TileTapped>(_onTileTapped);
on<PuzzleReset>(_onPuzzleReset);
}
  void _onPuzzleInitialized(
PuzzleInitialized event,
Emitter<PuzzleState> emit,
) {...}
void _onTileTapped(
TileTapped event,
Emitter<PuzzleState> emit,
) {...}
void _onPuzzleReset(
PuzzleReset event,
Emitter<PuzzleState> emit,
) {...}
}

自訂主題

樣本拼圖程式碼包含 Simple 和 Dashatar 兩種主題。這些可以用作您自訂主題的起點 - 盡情借用所需部分,或從頭開始。您如何實作拼圖取決於您自己!您可以考慮發揮創造力的其中一個地方是拼圖主題。

Flutter slide puzzle with Dash in the lower right corner

所有演示中的主題都在 PuzzlePage 的頂部發生。它已抽象化,因此您只需要更新一個地方的主題元素,更改就會反映到所有地方。Simple 和 Dashatar 主題都定義了一系列選項,例如螢幕背景、選單、標誌、按鈕、文字顏色、主題是否顯示計時器(Dashatar 主題中出現,但 Simple 主題中沒有),等等。您可以在儲存庫根目錄的「dashatar」和「simple」目錄中找到它們。

/// {@template simple_theme}
/// The simple puzzle theme.
/// {@endtemplate}
class SimpleTheme extends PuzzleTheme {
/// {@macro simple_theme}
const SimpleTheme() : super();
  @override
Color get backgroundColor => PuzzleColors.white;
  @override
Color get buttonColor => PuzzleColors.primary6;
  @override
Color get hoverColor => PuzzleColors.primary3;
  @override
Color get pressedColor => PuzzleColors.primary7;
  ...
}

每個拼圖主題都有一個 LayoutDelegate,它計算該主題的佈局。您可以透過重複使用相同的佈局物件,僅調整一些主題選項來建立新的主題。對於更進階的設計,整個主題 LayoutDelegate 都可以自訂。例如,您可以覆寫 backgroundBuilder 以製作自訂背景,僅在大型螢幕上顯示。

@override
Widget backgroundBuilder(PuzzleState state) {
return Positioned(
bottom: 74,
right: 50,
child: ResponsiveLayoutBuilder(
small: (_, child) => const SizedBox(),
medium: (_, child) => const SizedBox(),
large: (_, child) => const DashatarThemePicker(),
),
);
}

實作動畫

動畫是您在滑動拼圖中探索的絕佳元素。雖然 Simple 主題不包含任何動畫,但 Dashatar 程式碼實作了一些動畫,其中一些是 [交錯](https://docs.flutter.dev/development/ui/animations/staggered-animations) 的。這些動畫由單一動畫控制器驅動,使用 [Interval](https://api.flutter.dev/flutter/animation/Interval-class.html) 調整以延遲動畫,並使用 [Tween](https://api.flutter.dev/flutter/animation/Tween-class.html) 定義動畫的數值範圍。這可以在 Dashatar 拼圖的成功狀態中看到,其中多個 Widget 透過動畫其偏移量和不透明度而逐漸出現。類似地,倒計時器的每個滴答都使用相同的技術,緩慢地增長然後淡出,就像下一個滴答即將出現一樣。

Dashatar slide puzzle mid-shuffle with a puzzle timer above

Dashatar 主題中的大多數動畫都是隱含的。這表示您無需自行撰寫整個動畫,因為 Widget 會自行對屬性更改進行動畫。舉例來說,請查看 DashatarPuzzleTile Widget,了解如何對使用者點擊磁磚時磁磚的移動進行動畫。每當點擊磁磚時,其目前的 position 會更新,並透過隱含動畫的 AnimatedAlign 在給定的 movementDuration 內轉場。

class DashatarPuzzleTile extends StatelessWidget {
...

final Tile tile;

@override
Widget build(BuildContext context) {
return AnimatedAlign(
alignment: FractionalOffset(
(tile.currentPosition.x - 1) / (size - 1),
(tile.currentPosition.y - 1) / (size - 1),
),
duration: movementDuration,
curve: Curves.easeInOut,
child: ResponsiveLayoutBuilder(...),
);
}
}

為網頁設計

樣本拼圖是為網頁而建的。它為三個螢幕尺寸實作了響應式設計:小型、中型和大型。此外,還有一個 ResponsiveLayoutBuilder,它使用 Flutter LayoutBuilder Widget 的包裝器,允許您根據不同的斷點指定不同的 Widget。

由於我們以網頁為目標,因此有一些額外的注意事項需要牢記。應用程式會預先快取圖片和一些音訊,以幫助優化遊戲期間的效能。當使用者到達預設的 Simple 拼圖遊戲時,Dashatar 版本的資產會在後台載入(我們對 [I/O 照片亭](https://github.com/flutter/photobooth) 載入所有道具的方式採取了類似的方法)。這將確保一旦使用者導航到 Dashatar 主題,大多數資產將已經載入,確保順暢的使用者體驗。

雖然應用程式在網頁上很方便,但您可以挑戰自己探索以創新方式讓拼圖擴展到多個平台的方法。您的拼圖在行動裝置和桌面上會是什麼樣子?您如何為多個平台調整您的想法?

無障礙性

滑動拼圖的設計考慮了無障礙性。使用者可以使用鍵盤與拼圖互動。這是透過 RawKeyboardListener 完成的,RawKeyboardListener 是一個在使用者按下或放開鍵盤上的鍵時會呼叫回呼的 Widget。使用者也可以使用螢幕閱讀器與應用程式互動。這是透過 [語義標籤](https://api.flutter.dev/flutter/widgets/Semantics-class.html) 完成的。還有一些提示,使用 Tooltip Widget 為某些操作顯示。如果您要從頭開始建立滑動拼圖提交,我們強烈建議使用上面類似的策略,使您的拼圖對所有使用者都具有無障礙性。

額外想法

您可以隨意使用演示程式碼庫作為您的提交的基礎。或者,您可以從頭開始實作一個新想法。重要的是您的提交是一個有效的滑動拼圖 - 但您如何實現它取決於您自己!

Simple 和 Dashatar 範例應該可以讓您了解您可以自訂的地方,或者您可以自行建立的酷炫事物。我們探索的一個有趣想法是將 [由 Felix Blaschke 建立的 Flutter Plasma](https://flutterplasma.dev/) 投影到拼圖磁磚上。電漿效果可以使用包裝在 Transform Widget 中的 CustomPaint Widget 實現,並使用 AnimationController 進行動畫。您可以在 [此處](https://github.com/felixblaschke/sa3_liquid/blob/main/lib/liquid/plasma/plasma.dart) 找到用在演示中的電漿渲染器的範例。

Slide puzzle with plasma gradient effect displayed on the tiles and rockstar Dash in the lower right corner

另一個想法是從 API 擷取圖片或其他資料。例如,您可以使用 [Google 照片 API](https://developers.google.com/photos) 使用您最喜歡的 Google 照片相簿中的照片製作滑動拼圖。這個挑戰的可能性是無限的!

在此查看樣本拼圖程式碼 [here](https://github.com/VGVentures/slide_puzzle)。在 Twitter 上使用 #FlutterPuzzleHack 與我們分享您的創作。我們迫不及待想看看您會建立什麼!


如何建立您自己的 Flutter 滑動拼圖 最初發佈在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。