Chuyển đến nội dung chính

Bài đăng

Hiển thị các bài đăng có nhãn Migration

material_ui và cupertino_ui độc lập: thay đổi gì ở bản 1.0

Material và Cupertino từng bị “đóng băng” bên trong core SDK. Mọi cập nhật design phải đợi nhịp release quarterly của Flutter. Ở Flutter 3.47, cả hai thư viện đạt 1.0 dạng package độc lập trên pub.dev: material_ui và cupertino_ui . Bản trong SDK vẫn còn ở release này. Package là opt-in . Đó là chủ đích — team đóng contribution từ tháng 4 để đường migrate nhàm chán nhất có thể. Vì sao cần tách trong năm 2026 Release design hàng tuần. Bugfix và component mới không còn chờ flutter upgrade . Upgrade độc lập. App ghim SDK cũ vẫn update được look-and-feel mới. Core trung lập style. Nền tảng gọn hơn cho design system riêng (và cú sốc Liquid Glass / M3 Expressive từ vendor). Migrate bằng dart fix flutter pub add material_ui # nếu dùng Cupertino: flutter pub add cupertino_ui dart fix --apply --code=migrate_design_widgets Lệnh này rewrite import từ package:flutter/material.dart / cupertino.dart sang package mới. Nếu pubspec.yaml không tự đổi (bug sớm đã biết), thê...

Migrating to standalone material_ui and cupertino_ui in Flutter 3.47 — hướng dẫn Flutter

Flutter 3.47 ships opt-in standalone design packages at 1.0. Design updates no longer wait on the quarterly SDK train. Bài này chuyển quan sát đó thành một mô hình nhỏ để bạn có thể kiểm thử, đo lường và giữ cho code dễ bảo trì khi app lớn lên. Vấn đề cốt lõi How to move off SDK-bundled Material/Cupertino with dart fix and the compatibility bridge. Câu hỏi hữu ích không phải API hay pattern có đẹp riêng lẻ hay không, mà là state nằm ở đâu, boundary nào chịu trách nhiệm khi lỗi xảy ra, và người dùng phục hồi thế nào khi happy path biến mất. Mô hình thực tế Weekly releases, independent upgrades, and a style-neutral core for custom design systems and platform design shocks. Hãy bắt đầu bằng một owner rõ ràng cho behavior. Widget chỉ nên render và phát intent; IO, persistence, permission và retry nên nằm sau một interface nhỏ. Nhờ vậy bạn có seam để fake trong test và một chỗ ghi lại các dữ kiện cần theo dõi ở production. Trong app Flutter, boundary thường có dạng: Widget phát int...

Standalone material_ui and cupertino_ui: what the 1.0 split changes

Material and Cupertino used to be frozen inside the core SDK. That made design updates wait on the quarterly Flutter release train. In Flutter 3.47 both libraries reach 1.0 as standalone packages on pub.dev: material_ui and cupertino_ui . You still get the SDK copies this release. The packages are opt-in . That is deliberate — the team froze contributions in April so the migration path could be boring. Why the split matters in 2026 Three concrete outcomes: Weekly design releases. Bugfixes and new components no longer wait for flutter upgrade . Independent upgrades. An app pinned to an older SDK can still take the latest look and feel. Style-neutral core. A leaner foundation for custom design systems (and for Liquid Glass / M3 Expressive-style shocks from platform vendors). Migrate with dart fix flutter pub add material_ui # if you use Cupertino: flutter pub add cupertino_ui dart fix --apply --code=migrate_design_widgets The fix rewrites imports from packag...

Migrating to standalone material_ui and cupertino_ui in Flutter 3.47

Flutter 3.47 ships opt-in standalone design packages at 1.0. Design updates no longer wait on the quarterly SDK train. This article turns that observation into a small implementation model you can test, measure, and keep boring when the app grows. The problem in one sentence How to move off SDK-bundled Material/Cupertino with dart fix and the compatibility bridge. The useful question is not whether the API or pattern looks elegant in isolation. It is where state lives, which boundary owns failure, and how a user recovers when the happy path disappears. A practical model Weekly releases, independent upgrades, and a style-neutral core for custom design systems and platform design shocks. Start with one explicit owner for the behavior. Keep widgets responsible for rendering and user intent; keep IO, persistence, permissions, and retries behind a small interface. That gives you a seam for a fake in tests and a place to record the facts that matter in production. For a Flutter app, t...

Moving Android XML / UIKit apps to Flutter gradually — hướng dẫn Flutter

You do not have to rewrite everything to start with Flutter. Bài này chuyển quan sát đó thành một mô hình nhỏ để bạn có thể kiểm thử, đo lường và giữ cho code dễ bảo trì khi app lớn lên. Vấn đề cốt lõi Add-to-app first screens and shared navigation contracts. Câu hỏi hữu ích không phải API hay pattern có đẹp riêng lẻ hay không, mà là state nằm ở đâu, boundary nào chịu trách nhiệm khi lỗi xảy ra, và người dùng phục hồi thế nào khi happy path biến mất. Mô hình thực tế One high-churn feature is a better pilot than a settings page. Hãy bắt đầu bằng một owner rõ ràng cho behavior. Widget chỉ nên render và phát intent; IO, persistence, permission và retry nên nằm sau một interface nhỏ. Nhờ vậy bạn có seam để fake trong test và một chỗ ghi lại các dữ kiện cần theo dõi ở production. Trong app Flutter, boundary thường có dạng: Widget phát intent như load, submit, refresh hoặc retry. Controller hoặc use case validate intent rồi gọi boundary. Boundary trả về data có kiểu hoặc failure c...

Migrating from React Native to Flutter in 2026 — hướng dẫn Flutter

Big-bang rewrites fail. Strangle features behind a shared shell. Bài này chuyển quan sát đó thành một mô hình nhỏ để bạn có thể kiểm thử, đo lường và giữ cho code dễ bảo trì khi app lớn lên. Vấn đề cốt lõi Strangler patterns, design system mapping, and risk. Câu hỏi hữu ích không phải API hay pattern có đẹp riêng lẻ hay không, mà là state nằm ở đâu, boundary nào chịu trách nhiệm khi lỗi xảy ra, và người dùng phục hồi thế nào khi happy path biến mất. Mô hình thực tế Map design tokens first; ports second. Hãy bắt đầu bằng một owner rõ ràng cho behavior. Widget chỉ nên render và phát intent; IO, persistence, permission và retry nên nằm sau một interface nhỏ. Nhờ vậy bạn có seam để fake trong test và một chỗ ghi lại các dữ kiện cần theo dõi ở production. Trong app Flutter, boundary thường có dạng: Widget phát intent như load, submit, refresh hoặc retry. Controller hoặc use case validate intent rồi gọi boundary. Boundary trả về data có kiểu hoặc failure có kiểu, không trả string ...

Migrating large apps to Material 3 Expressive — hướng dẫn Flutter

M3 migrations fail when done as big-bang UI rewrites. Bài này chuyển quan sát đó thành một mô hình nhỏ để bạn có thể kiểm thử, đo lường và giữ cho code dễ bảo trì khi app lớn lên. Vấn đề cốt lõi Component themes, regression goldens, and staged rollout. Câu hỏi hữu ích không phải API hay pattern có đẹp riêng lẻ hay không, mà là state nằm ở đâu, boundary nào chịu trách nhiệm khi lỗi xảy ra, và người dùng phục hồi thế nào khi happy path biến mất. Mô hình thực tế Stage by feature flag; use goldens for visual regression. Hãy bắt đầu bằng một owner rõ ràng cho behavior. Widget chỉ nên render và phát intent; IO, persistence, permission và retry nên nằm sau một interface nhỏ. Nhờ vậy bạn có seam để fake trong test và một chỗ ghi lại các dữ kiện cần theo dõi ở production. Trong app Flutter, boundary thường có dạng: Widget phát intent như load, submit, refresh hoặc retry. Controller hoặc use case validate intent rồi gọi boundary. Boundary trả về data có kiểu hoặc failure có kiểu, khôn...

Moving Android XML / UIKit apps to Flutter gradually

You do not have to rewrite everything to start with Flutter. This article turns that observation into a small implementation model you can test, measure, and keep boring when the app grows. The problem in one sentence Add-to-app first screens and shared navigation contracts. The useful question is not whether the API or pattern looks elegant in isolation. It is where state lives, which boundary owns failure, and how a user recovers when the happy path disappears. A practical model One high-churn feature is a better pilot than a settings page. Start with one explicit owner for the behavior. Keep widgets responsible for rendering and user intent; keep IO, persistence, permissions, and retries behind a small interface. That gives you a seam for a fake in tests and a place to record the facts that matter in production. For a Flutter app, the boundary usually looks like this: The widget emits an intent such as load, submit, refresh, or retry. A controller or use case validates the...

Migrating from React Native to Flutter in 2026

Big-bang rewrites fail. Strangle features behind a shared shell. This article turns that observation into a small implementation model you can test, measure, and keep boring when the app grows. The problem in one sentence Strangler patterns, design system mapping, and risk. The useful question is not whether the API or pattern looks elegant in isolation. It is where state lives, which boundary owns failure, and how a user recovers when the happy path disappears. A practical model Map design tokens first; ports second. Start with one explicit owner for the behavior. Keep widgets responsible for rendering and user intent; keep IO, persistence, permissions, and retries behind a small interface. That gives you a seam for a fake in tests and a place to record the facts that matter in production. For a Flutter app, the boundary usually looks like this: The widget emits an intent such as load, submit, refresh, or retry. A controller or use case validates the intent and calls the bou...

Migrating large apps to Material 3 Expressive

M3 migrations fail when done as big-bang UI rewrites. This article turns that observation into a small implementation model you can test, measure, and keep boring when the app grows. The problem in one sentence Component themes, regression goldens, and staged rollout. The useful question is not whether the API or pattern looks elegant in isolation. It is where state lives, which boundary owns failure, and how a user recovers when the happy path disappears. A practical model Stage by feature flag; use goldens for visual regression. Start with one explicit owner for the behavior. Keep widgets responsible for rendering and user intent; keep IO, persistence, permissions, and retries behind a small interface. That gives you a seam for a fake in tests and a place to record the facts that matter in production. For a Flutter app, the boundary usually looks like this: The widget emits an intent such as load, submit, refresh, or retry. A controller or use case validates the intent and ...

Moving Android XML / UIKit apps to Flutter gradually — hướng dẫn Flutter

You do not have to rewrite everything to start with Flutter. Bài này chuyển quan sát đó thành một mô hình nhỏ để bạn có thể kiểm thử, đo lường và giữ cho code dễ bảo trì khi app lớn lên. Vấn đề cốt lõi Add-to-app first screens and shared navigation contracts. Câu hỏi hữu ích không phải API hay pattern có đẹp riêng lẻ hay không, mà là state nằm ở đâu, boundary nào chịu trách nhiệm khi lỗi xảy ra, và người dùng phục hồi thế nào khi happy path biến mất. Mô hình thực tế One high-churn feature is a better pilot than a settings page. Hãy bắt đầu bằng một owner rõ ràng cho behavior. Widget chỉ nên render và phát intent; IO, persistence, permission và retry nên nằm sau một interface nhỏ. Nhờ vậy bạn có seam để fake trong test và một chỗ ghi lại các dữ kiện cần theo dõi ở production. Trong app Flutter, boundary thường có dạng: Widget phát intent như load, submit, refresh hoặc retry. Controller hoặc use case validate intent rồi gọi boundary. Boundary trả về data có kiểu hoặc failure c...

Migrating from React Native to Flutter in 2026 — hướng dẫn Flutter

Big-bang rewrites fail. Strangle features behind a shared shell. Bài này chuyển quan sát đó thành một mô hình nhỏ để bạn có thể kiểm thử, đo lường và giữ cho code dễ bảo trì khi app lớn lên. Vấn đề cốt lõi Strangler patterns, design system mapping, and risk. Câu hỏi hữu ích không phải API hay pattern có đẹp riêng lẻ hay không, mà là state nằm ở đâu, boundary nào chịu trách nhiệm khi lỗi xảy ra, và người dùng phục hồi thế nào khi happy path biến mất. Mô hình thực tế Map design tokens first; ports second. Hãy bắt đầu bằng một owner rõ ràng cho behavior. Widget chỉ nên render và phát intent; IO, persistence, permission và retry nên nằm sau một interface nhỏ. Nhờ vậy bạn có seam để fake trong test và một chỗ ghi lại các dữ kiện cần theo dõi ở production. Trong app Flutter, boundary thường có dạng: Widget phát intent như load, submit, refresh hoặc retry. Controller hoặc use case validate intent rồi gọi boundary. Boundary trả về data có kiểu hoặc failure có kiểu, không trả string ...

Migrating large apps to Material 3 Expressive — hướng dẫn Flutter

M3 migrations fail when done as big-bang UI rewrites. Bài này chuyển quan sát đó thành một mô hình nhỏ để bạn có thể kiểm thử, đo lường và giữ cho code dễ bảo trì khi app lớn lên. Vấn đề cốt lõi Component themes, regression goldens, and staged rollout. Câu hỏi hữu ích không phải API hay pattern có đẹp riêng lẻ hay không, mà là state nằm ở đâu, boundary nào chịu trách nhiệm khi lỗi xảy ra, và người dùng phục hồi thế nào khi happy path biến mất. Mô hình thực tế Stage by feature flag; use goldens for visual regression. Hãy bắt đầu bằng một owner rõ ràng cho behavior. Widget chỉ nên render và phát intent; IO, persistence, permission và retry nên nằm sau một interface nhỏ. Nhờ vậy bạn có seam để fake trong test và một chỗ ghi lại các dữ kiện cần theo dõi ở production. Trong app Flutter, boundary thường có dạng: Widget phát intent như load, submit, refresh hoặc retry. Controller hoặc use case validate intent rồi gọi boundary. Boundary trả về data có kiểu hoặc failure có kiểu, khôn...

Brand refreshes without breaking mobile users — hướng dẫn Flutter

Rebrands are migrations. Stage them. Bài này chuyển quan sát đó thành một mô hình nhỏ để bạn có thể kiểm thử, đo lường và giữ cho code dễ bảo trì khi app lớn lên. Vấn đề cốt lõi Token stages, co-existing themes, and migration UX. Câu hỏi hữu ích không phải API hay pattern có đẹp riêng lẻ hay không, mà là state nằm ở đâu, boundary nào chịu trách nhiệm khi lỗi xảy ra, và người dùng phục hồi thế nào khi happy path biến mất. Mô hình thực tế Support old/new themes behind a flag for one release. Hãy bắt đầu bằng một owner rõ ràng cho behavior. Widget chỉ nên render và phát intent; IO, persistence, permission và retry nên nằm sau một interface nhỏ. Nhờ vậy bạn có seam để fake trong test và một chỗ ghi lại các dữ kiện cần theo dõi ở production. Trong app Flutter, boundary thường có dạng: Widget phát intent như load, submit, refresh hoặc retry. Controller hoặc use case validate intent rồi gọi boundary. Boundary trả về data có kiểu hoặc failure có kiểu, không trả string chỉ dành cho l...

Brand refreshes without breaking mobile users

Rebrands are migrations. Stage them. This article turns that observation into a small implementation model you can test, measure, and keep boring when the app grows. The problem in one sentence Token stages, co-existing themes, and migration UX. The useful question is not whether the API or pattern looks elegant in isolation. It is where state lives, which boundary owns failure, and how a user recovers when the happy path disappears. A practical model Support old/new themes behind a flag for one release. Start with one explicit owner for the behavior. Keep widgets responsible for rendering and user intent; keep IO, persistence, permissions, and retries behind a small interface. That gives you a seam for a fake in tests and a place to record the facts that matter in production. For a Flutter app, the boundary usually looks like this: The widget emits an intent such as load, submit, refresh, or retry. A controller or use case validates the intent and calls the boundary. The bo...

Migrating to standalone material_ui and cupertino_ui in Flutter 3.47

Flutter 3.47 ships opt-in standalone design packages at 1.0. Design updates no longer wait on the quarterly SDK train. This article turns that observation into a small implementation model you can test, measure, and keep boring when the app grows. The problem in one sentence How to move off SDK-bundled Material/Cupertino with dart fix and the compatibility bridge. The useful question is not whether the API or pattern looks elegant in isolation. It is where state lives, which boundary owns failure, and how a user recovers when the happy path disappears. A practical model Weekly releases, independent upgrades, and a style-neutral core for custom design systems and platform design shocks. Start with one explicit owner for the behavior. Keep widgets responsible for rendering and user intent; keep IO, persistence, permissions, and retries behind a small interface. That gives you a seam for a fake in tests and a place to record the facts that matter in production. For a Flutter app, t...

Moving Android XML / UIKit apps to Flutter gradually

You do not have to rewrite everything to start with Flutter. This article turns that observation into a small implementation model you can test, measure, and keep boring when the app grows. The problem in one sentence Add-to-app first screens and shared navigation contracts. The useful question is not whether the API or pattern looks elegant in isolation. It is where state lives, which boundary owns failure, and how a user recovers when the happy path disappears. A practical model One high-churn feature is a better pilot than a settings page. Start with one explicit owner for the behavior. Keep widgets responsible for rendering and user intent; keep IO, persistence, permissions, and retries behind a small interface. That gives you a seam for a fake in tests and a place to record the facts that matter in production. For a Flutter app, the boundary usually looks like this: The widget emits an intent such as load, submit, refresh, or retry. A controller or use case validates the...

Migrating from React Native to Flutter in 2026

Big-bang rewrites fail. Strangle features behind a shared shell. This article turns that observation into a small implementation model you can test, measure, and keep boring when the app grows. The problem in one sentence Strangler patterns, design system mapping, and risk. The useful question is not whether the API or pattern looks elegant in isolation. It is where state lives, which boundary owns failure, and how a user recovers when the happy path disappears. A practical model Map design tokens first; ports second. Start with one explicit owner for the behavior. Keep widgets responsible for rendering and user intent; keep IO, persistence, permissions, and retries behind a small interface. That gives you a seam for a fake in tests and a place to record the facts that matter in production. For a Flutter app, the boundary usually looks like this: The widget emits an intent such as load, submit, refresh, or retry. A controller or use case validates the intent and calls the bou...

Migrating large apps to Material 3 Expressive

M3 migrations fail when done as big-bang UI rewrites. This article turns that observation into a small implementation model you can test, measure, and keep boring when the app grows. The problem in one sentence Component themes, regression goldens, and staged rollout. The useful question is not whether the API or pattern looks elegant in isolation. It is where state lives, which boundary owns failure, and how a user recovers when the happy path disappears. A practical model Stage by feature flag; use goldens for visual regression. Start with one explicit owner for the behavior. Keep widgets responsible for rendering and user intent; keep IO, persistence, permissions, and retries behind a small interface. That gives you a seam for a fake in tests and a place to record the facts that matter in production. For a Flutter app, the boundary usually looks like this: The widget emits an intent such as load, submit, refresh, or retry. A controller or use case validates the intent and ...

Brand refreshes without breaking mobile users — hướng dẫn Flutter

Rebrands are migrations. Stage them. Bài này chuyển quan sát đó thành một mô hình nhỏ để bạn có thể kiểm thử, đo lường và giữ cho code dễ bảo trì khi app lớn lên. Vấn đề cốt lõi Token stages, co-existing themes, and migration UX. Câu hỏi hữu ích không phải API hay pattern có đẹp riêng lẻ hay không, mà là state nằm ở đâu, boundary nào chịu trách nhiệm khi lỗi xảy ra, và người dùng phục hồi thế nào khi happy path biến mất. Mô hình thực tế Support old/new themes behind a flag for one release. Hãy bắt đầu bằng một owner rõ ràng cho behavior. Widget chỉ nên render và phát intent; IO, persistence, permission và retry nên nằm sau một interface nhỏ. Nhờ vậy bạn có seam để fake trong test và một chỗ ghi lại các dữ kiện cần theo dõi ở production. Trong app Flutter, boundary thường có dạng: Widget phát intent như load, submit, refresh hoặc retry. Controller hoặc use case validate intent rồi gọi boundary. Boundary trả về data có kiểu hoặc failure có kiểu, không trả string chỉ dành cho l...